Discussion in "8051 Discussion Forum" started by    Help    Dec 8, 2008.
Tue Feb 10 2009, 09:03 pm
#91
Hi Shivaprasad,

This memset function is to asign a number to your buff.

it something like this code bellow
while(buff[i]=2, i<128);

Gd Luck,.
Tue Feb 10 2009, 10:09 pm
#92
The mem... functions are meant for manipulating objects as character arrays; the intent is an interface to efficient routines. In the following table, s and t are of type void *; cs and ct are of type const void *; n is of type size_t; and c is an int converted to an unsigned char.
void *memcpy(s,ct,n)	//copy n characters from ct to s, and return s.
void *memmove(s,ct,n)	//same as memcpy except that it works even if the objects overlap.
int memcmp(cs,ct,n)	//compare the first n characters of cs with ct; return as with strcmp.
void *memchr(cs,c,n)	//return pointer to first occurrence of character c in cs, or NULL if not present among the first n characters.
void *memset(s,c,n)	//place character c into first n characters of s, return s.
Tue Feb 10 2009, 11:31 pm
#93
Okay, here goes nothing:

Chan's code looks like this:

void scan_files (char* path)
{
    FILINFO finfo;
    DIR dirs;
    int i;

    if (f_opendir(&dirs, path) == FR_OK) {
        i = strlen(path);
        while ((f_readdir(&dirs, &finfo) == FR_OK) && finfo.fname[0]) {
            if (finfo.fattrib & AM_DIR) {
                sprintf(&path[i], "/%s", &finfo.fname[0]);
                scan_files(path);
                path[i] = 0;
            } else {
                printf("%s/%s\n", path, &finfo.fname[0]);
            }
        }
    }
}

If you read the documentation for the f_opendir(...) function, you will see the following:

The f_opendir function opens an exsisting directory and creates the directory object for subsequent calls. The directory object structure can be discarded at any time without any procedure. This function is not supported in minimization level of >=2.


If you read the documentation for the f_readdir(...) function, you will see the following:

The f_readdir function reads directory entries in sequence. All items in the directory can be read by calling f_readdir function repeatedly. When all directory items have been read and no item to read, the function returns a null string into f_name[] member without any error. For details of the file informations, refer to the FILINFO. This function is not supported in minimization level of >=2.


Now, what does this mean? Well, based on the first function (f_opendir()), Chan is opening an existing directory and creating a directory object for subsequent ( following ) calls. The directory object (in this case, he calls it dirs) will be used as a reference to which directory he is referring to when he calls the function f_readdir().
Remember, he can have multiple directories, so he needs to keep track of which one he's currently using...
The first call to f_opendir(), of course, refers to the root directory.

Chan then starts a repeat loop, reading each directory entry as long as the read function is OK, and the first character in the name is NOT ZERO. Remember, in the FAT, when a filename starts with zero (0x00), it is considered an empty place holder, and can be considered the end of entries in the directory

Once he has read a directory entry, he checks to see if it is an actual file, or if it is a sub-directory
This is done by checking the attribute flags. I modified my code to check all of the flags, and show them, like this:
      while( (f_readdir(&dirs, &finfo) == FR_OK) && finfo.fname[0] ) 
         {
         putchar('[');
         putchar(( finfo.fattrib & AM_RDO ) ? 'r' : '.');
         putchar(( finfo.fattrib & AM_HID ) ? 'h' : '.');
         putchar(( finfo.fattrib & AM_SYS ) ? 's' : '.');
         putchar(( finfo.fattrib & AM_VOL ) ? 'v' : '.');
         putchar(( finfo.fattrib & AM_LFN ) ? 'l' : '.');
         putchar(( finfo.fattrib & AM_DIR ) ? 'd' : '.');
         putchar(( finfo.fattrib & AM_ARC ) ? 'a' : '.');
         putchar(']');


Anyway, Chan checks the flag AM_DIR to see if the file entry is actually a sub-directory, not a file. If it is a sub-directory, he changes the current path (which is 0x00, or the root directory) to the sub-directory name by overwriting the variable *path, calls scan_files() again, which will print out all of the files within the sub directory, and when it returns, resets the *path to 0x00 again to continue.

This is a classic example of recursion, and in a normal C environment, this would work just fine, since passed arguments are stored on the stack. This will NOT, however, work well on our microcontroller, since all of the arguments have real addresses, and are not stored on the small stack.

More to come soon...
Wed Feb 11 2009, 12:30 am
#94
Okay, so getting back to recursion... Don't worry about it yet, I'll show you how in a minute...

On closer inspection of Chan's code, however, we focus on this section:

sprintf(&path[i], "/%s", &finfo.fname[0]);
scan_files(path);
path[i] = 0;


What's wrong with this? Let's say that our Directory structure looks like this:
root directory:
file1.txt
file2.txt
subdir1
file5.txt

subdir1:
file3.txt
file4.txt

If we use the scan_files() function the way it is right now (assuming we could support recursion), our output would look like this:
0:/file1.txt
0:/file2.txt
0:/subdir1/file3.txt
0:/subdir1/file4.txt
0:/file5.txt

No problem, right? But what if our Directory structure looks like this:
root directory:
file1.txt
file2.txt
subdir1
file7.txt

subdir1:
file3.txt
file4.txt
subdir2
file6.txt

subdir2:
file5.txt

Now our output would look like this:
0:/file1.txt
0:/file2.txt
0:/subdir1/file3.txt
0:/subdir1/file4.txt
0:/subdir1/subdir2/file5.txt
0:/file7.txt

So what happened to file6.txt????? The problem with the scan_files() function is the statement after the recursive call. It resets the path to the root directory, instead of the last path, which in the second example above, should have been subdir1...

The way to fix this is to keep a local copy of the path within the function, and restore this local copy after you return from the recursive call to scan_files()...

Okay, so how do you do recursion? In Keil C51, recursion is achieved by setting up a simulated stack, and using the reserved word REENTRANT. It also requires the COMPACT memory model...

If you read this description, it will be clearer to you:

http://www.keil.com/support/docs/1873.htm

But doesn't this make things difficult to understand? Isn't there a way to avoid the recurssive calls and simplify the software?

Yes, but it either requires you to have a limit to how deep your subdirectories can go, or it requires you to dynamically allocate memory for directory variables each time you go down 1 subdirectory level...

The choice is yours...

If you just ignore subdirectories for now, and concentrate on getting things working, you can rewrite Chan's routine so it only shows the files in the root directory. It would look like this:
void scan_files (char* path)
   {
   FILINFO finfo;
   DIR dirs;
   int i;
   
   if (f_opendir(&dirs, path) == FR_OK) 
      {
      i = strlen(path);
      while ((f_readdir(&dirs, &finfo) == FR_OK) && finfo.fname[0]) 
         printf("%s/%s\n", path, &finfo.fname[0]);
      }
   }


I hope this helps you, Tang

-db
 ajay_bhargav like this.
Wed Feb 11 2009, 02:27 am
#95
Thanks dave very nice description you should tell chan about this bug. and say thanks to him
Wed Feb 11 2009, 03:26 am
#96
I already thanked him in his BBS at:
http://elm-chan.org/bbs/?lang=en&show=5810
under #5810 tff.c by David-San 1/29/2009, 9:13 JST
Regarding the bug: it's only my opinion it is wrong. For all I know, that's how he wanted it...

-Dave
Wed Feb 11 2009, 11:13 am
#97

Working on a permutation of the directory list function that I can share with everyone...
Wed Feb 11 2009, 07:02 pm
#98
Hello friends,

Presently I have created some text files in the sd card through computer. I noticed that the information about these files are stored into sector 4153. but I cant understand some of the values realted to that. I have figured some of the information about the file name, extension,time and date, type of document and the cluster that it is getting stored and the size it is occupying. but DavesGarage said that the information of present file i.e where the next cluster starts for the particular file is stored in the FAT. I didn't get this information. where can I find this. Please help me...



shiva
Wed Feb 11 2009, 07:10 pm
#99
From shiva



[ Edited Thu Feb 12 2009, 02:05 am ]
Thu Feb 12 2009, 01:12 am
Welcome to this thread, Shiva...

I'll see if I can explain what I've learned so far:

First, if you look at your data dump above, there are several things you automatically realize about your SD card:

1. Your DirectoryAddress starts at 0x00207200 - This is the beginning of the directory cluster, and the very first entry ( 11 bytes long ) says "MYDISK ", which is the volume label on your disk. Also, since the adderss is 0x00207200, and your sector size is 0x200 bytes long ( 512 bytes ), you know that the DirectorySectorAddress is 0x00207200 / 0x200, or 0x00001039.

2. Since each entry in the directory table takes up 32 bytes, and entries that have been previously been deleted start with 0xE5, you can see that the first three (3) entries were previously deleted. The fourth entry, however, starts with a valid character, and therefore is a file. The name of this file is "SHVA.TXT", and it takes up the first 11 bytes. The next byte is the attribute byte, and because it is 0x20, you know this file has the ARCHIVE bit set.



3. You can see the time and date information about when the file was created in bytes 0x8F, 0x94 and 0x4B, 0x3A, which tell us the file was created at 6:36:30 PM on 2/11/2009, which means you were playing on your computer when you were suppose to be having dinner. :blush

4. You can see where the data starts (the first cluster) is 0x000D, and you can see that the file is 0x00001E90 bytes long (7824)...

Now...

What you cannot see is the size of each cluster. This is suppose to be calculated from your boot sector information. You also cannot see your FAT information, which is located at the FatSectorAddress, again calculated from your boot sector information.

When you calculate these missing pieces of information, and use them with the information from above, you will see that the FatAddress[ 0x000D * 2 ] will have a value in it ( probably 0x000E ), which is the cluster number for the second piece of your file - Remember, the file information told you the file data actually starts at cluster 0x000D. After you read that cluster, you will see that the FatAddress[ 0x000E *2 ] will have a value in it ( probably 0x000F ), which is the cluster number for the third piece of your file...

And so on, and so on - until you come to a 0xFFFF in the FAT, which means that's it - no more clusters in this file...

Hope this helps,

-Dave

Get Social

Information

Powered by e107 Forum System

Downloads

Comments

gtaletrzua
Fri May 03 2024, 10:55 am
Clydehet
Wed May 01 2024, 06:44 pm
Davidoried
Wed May 01 2024, 06:11 pm
KevinTab
Sun Apr 28 2024, 05:35 am
Tumergix
Sun Apr 28 2024, 12:59 am
StevenDrulk
Sat Apr 27 2024, 08:47 pm
StephenHauct
Sat Apr 27 2024, 09:38 am
Adamsaf
Sat Apr 27 2024, 07:12 am