View previous topic :: View next topic |
Author |
Message |
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Fri Jul 01, 2011 10:31 am Post subject: |
|
|
you can use config base to let arrays start at 0. by default it starts at 1. _________________ Mark |
|
Back to top |
|
|
KokkeKat
Joined: 08 May 2011 Posts: 59 Location: Stockholm
|
Posted: Fri Jul 01, 2011 8:21 pm Post subject: |
|
|
Hi Mark
Thanks! I wasn't aware of this.
Kind regards
Niclas |
|
Back to top |
|
|
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Sat Jul 02, 2011 6:28 am Post subject: |
|
|
Hi Niclas,
You have answered my Q re msb/lsb first tnx.
I am now able to read and write to a number of different cards, but I am having trouble reading and writing to a file in a sub directory. I can create a sub dir OK, and can create files, append to them and read them, all in the root dir, but how do i create a file within that sub. (I want to store data in a remote datalogger into 2 files, and I assume because of the max no of entries allowed in the root dir, I should create my 2 files in a sub directory? My data logger will add 1000bytes of data every 15 minutes, and runs 24/7)
Running "example_find_avail_dir_entry.bas" gives me numbers for sddirclusterd =2 and sddirsecincluster=1 and sddirbufferpos =33 but I'm not sure ( ie I dont have a clue) what these numbers mean, or which file or sub or dir they refer to. I had 1 file in the root and 3 sub directories when I read those numbers, but they don't seem to change when I add new subs, or append to the file in the root dir.
regards
neil _________________ Neil |
|
Back to top |
|
|
KokkeKat
Joined: 08 May 2011 Posts: 59 Location: Stockholm
|
Posted: Sat Jul 02, 2011 10:15 am Post subject: |
|
|
Hi Neil
I would recommend you to read the pdf document found in the zip file, for a short explanation of the FAT16/32 file systems, but basically, the smallest addressable unit in the file system is a cluster. It contains 1-64 sectors, each with a certain number of bytes. (Only 512 bytes per sector is supported.)
Think like this: On a PC, when you want to create EXAMPLE.TXT in C:\TESTDIR\, you must first go to the root directory of C: and then enter subdirectory TESTDIR. There you create EXAMPLE.TXT.
With your AVR, you are now going to do the same thing. The root directory is represented by the first cluster in the cluster chain that constitutes the root. My lib calls it Sdclusterd 0. In this cluster chain you are now going to create a directory entry representing TESTDIR, that contains a pointer to the first cluster of TESTDIR. In this subdirectory cluster, a directory entry for EXAMPLE.TXT will be created, pointing to the first cluster for the new file.
A directory entry is 32 bytes long. If you are using Sddirlist, it will be placed in array Sddirlistdirentry(). Here is how you read the cluster pointer from the directory entry:
Sdclusterb(1) = Sddirlistdirentry(27)
Sdclusterb(2) = Sddirlistdirentry(28 )
Sdclusterb(3) = Sddirlistdirentry(21)
Sdclusterb(4) = Sddirlistdirentry(22)
For this example, assume we are only using 8.3 file names:
If you start with a freshly formatted SD card using FAT32, the root directory will start in cluster 2 (but refer to it as 0, for FAT16 compatibility). It will only contain a volume ID directory entry, which is initially placed in Sdsecincluster 1 at Sdbufferpos 1. Since a directory entry is 32 bytes long, the next directory entry will start at Sdbufferpos 33. Immediately after formatting, it will be empty and must be used for the next entry (that will refer to TESTDIR once you have created it). As the card is freshly formatted, the next available cluster is 3.
To create a subdirectory in root, use the code in Example_WRITE_SUBDIRECTORY.bas. After creation, Sdfatclusterd should contain the cluster number for the subdirectory.
To create EXAMPLE.TXT in TESTDIR, use the code in Example_WRITE_FILE.bas, but change it so that before calling, Sdstartdirclusterd = Sdfatclusterd (which in this example will be 3). EXAMPLE.TXT will start in the next available cluster, which is 4.
I hope this will help you along. Please share your progress.
(If you want to see the actual bytes of the SD card, try e.g. Winhex.)
Kind regards
Niclas |
|
Back to top |
|
|
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Sat Jul 02, 2011 11:40 am Post subject: |
|
|
Sorry Niclas, I have read the pdf - several times in fact; and your last missive many times, and done little drawings etc, but sorry it still makes no sense at all. I'll have another go tomorrow.
neil
_________________ Neil |
|
Back to top |
|
|
KokkeKat
Joined: 08 May 2011 Posts: 59 Location: Stockholm
|
Posted: Sat Jul 02, 2011 12:02 pm Post subject: |
|
|
Hi Neil
Please google for tutorials on FAT32. Make sure you understand:
* the concept of cluster chains
* the relationship between cluster / sector in cluster / byte in sector
* the FAT, file allocation table
* the directory structure
One place to start is (the second half of) this page:
http://www.pjrc.com/tech/8051/ide/fat32.html
Kind regards
Niclas |
|
Back to top |
|
|
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Sat Jul 02, 2011 12:39 pm Post subject: |
|
|
Niclas,
Do I need to bother with subdirectories - why can I simply put my files ( there will only be 2 or 3) in the root directory?
How big can these files be?
neil _________________ Neil |
|
Back to top |
|
|
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Sat Jul 02, 2011 12:43 pm Post subject: |
|
|
Alternatively- can I create the file names and subdirectories using a PC, and the simply append to the files using the AVR, knowing the file names only? _________________ Neil |
|
Back to top |
|
|
KokkeKat
Joined: 08 May 2011 Posts: 59 Location: Stockholm
|
Posted: Sat Jul 02, 2011 5:36 pm Post subject: |
|
|
Hi Neil
You can decide to only work with the root directory. I think the maximum number of files is 512 or 511 (or something like that).
You can create the directories and files with your PC (but I don't think you will gain much from it).
The maximum file size in FAT32 is 4GB-1. Please notice that such a big file will need 131 072 clusters of maximum cluster size (64*512 bytes * 131072 - 1 = 4294967295), so if you want to append to the file directly after powering up (in which case you don't yet know the "whereabouts" variables), it will take quite some time before your AVR has followed the cluster chain to the end.
You need to find the subdirectory's first cluster. Please see my latest posting in the topic named "List SUBDir" for an example. You always need to know the (first) cluster number for any directory. After that, just follow "Example_WRITE_FILE.bas".
Kind regards
Niclas |
|
Back to top |
|
|
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Sun Jul 03, 2011 7:16 am Post subject: |
|
|
Niclas, well after 2 days struggling, I seem to have more questions than answers.
Q1. You say in the sticky note, and somewhere else, that you can't have Sdusefind and sdusedirlist both =1. Why not?
Setting them to opposits means I cant run some of the examples in combination with each other, without running back and forth to the declarations and changing these 2 settings to get around missing declarations.? Setting them both =1 seems to save time, and hasn't caused a problem so far (I think?)
Q2. I have created several separate sub directories - or at least they show up on the PC as folders and not files, but they are empty, trying open them with a PC results in an error message to the effect that they dont exist or cant be read or something.
You said in one of your replies to me to set sdstatrtdirclusterd = sdfatclusterd. However I cant see how this works because sdfatclusterd is always =0, unless I have just created a file or direcytor, in which case it gets set in the createfile routine. Howver it still seems to write a file in the root dir even though I have it set as stated.
Then it begs the question - how do I writre in a sub when I have 2 sub directories present. Presumably I need to set sdfatclust with the value of the last used cluster in the sub that I want to write the file to? ( I note that preparetoappend dows this, which is probably how it appends to the ciorrect file?). How do I do the same with wrie file?
Q3. I assume subs need to have 8 char. I note that you use NEW FOLDA ( results in an 8.1 sub name) but elsewhere in a search and find routine, you use NEWFOLDA. Is this intentional?
Q4. How does a file, that has been written to a directory get referenced back to that directory ( not that I been able to do this yet) - is it when you call sdwritefsinfo?
Q5. Back to my application _ I have a data logger that is writing a 1000byte record 4 times per hour. Thats all. I am not reading it with _________________ Neil |
|
Back to top |
|
|
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Sun Jul 03, 2011 7:20 am Post subject: |
|
|
the micro - it will only be read with a PC, and the data imported into xcel for example. Each record is date/time stamped and all records have identical feilds. The question is - 365 files in the root per year, or 365 x 24 files in a sub, or 12 subs with 31 x 24 files each? _________________ Neil |
|
Back to top |
|
|
KokkeKat
Joined: 08 May 2011 Posts: 59 Location: Stockholm
|
Posted: Sun Jul 03, 2011 6:45 pm Post subject: |
|
|
Hi Neil
Please google for tutorials on FAT32. Make sure you understand:
* the concept of cluster chains
* the relationship between cluster / sector in cluster / byte in sector
* the FAT, file allocation table
* the directory structure
One place to start is (the second half of) this page:
http://www.pjrc.com/tech/8051/ide/fat32.html
---
A1: The two approaches provide practically the same functionality. If you enable both, you just waste program ROM. There could be different implementations of the same gosub names (but I don't remember), which could cause any kind of data corruption. However, you are free to adapt the code I have published for whatever your project needs are.
A2: Just to be sure, format the SD card in your PC again, so that you know that it is 100% ok. Once you have read up on FAT32, you'll understand the rest of this question.
A3: You'll have to read the FAT32 specification document for rules regarding file and subdirectory names. The file names you mention are just coincidental.
A4: Once you have read up on FAT32, you'll know the answer to this question.
A5: This is a design decision you will have to make. The point is that FAT12/16/32 has an inherent scaling limitation due to their use of cluster chains. You want to avoid getting too long cluster chains, regardless if it's a directory cluster chain or a file cluster chain.
With 8.3 names, you get 16 directory entries per sector. My 4GB SDHC card gets PC-formatted as 8 sectors per cluster, so each cluster stores (up to) 128 directory entries. This also happens to be the number of cluster pointers per FAT (File Allocation Table) sector. In this case, one subdirectory per month would result in 12 subdirectories with 4*24*31=2976 files. Each subdirectory would require 2976/16/8=23.25 (= 24) clusters for the directory chain (not including the actual file data). Each file would be 1000 bytes, but each file's (first and only) cluster would be sized 512*8=4096 bytes, so you waste 75% of each file's space. Whether this is good or bad depends on your particular design.
Alternatively, you could use one subdirectory per calendar week, or two levels of subdirectories (months and weeks). Ultimately, you need to read up on how FAT32 works.
Kind regards
Niclas |
|
Back to top |
|
|
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Fri Jul 08, 2011 7:18 am Post subject: create file in Sub |
|
|
Niclas,
what does sdwritefile.bas need to write a new file in a subdirectory? The addr of the first cluster of the directory, or the next free cluster? Its not clear to me which it needs. ( sotto voce " and please don't tell me to go and read the docs, because I have and its still not clear.")
If I set sdstartdirclusterd = sdfatclusterd (as you suggested) and run _writefile.bas, a file with the correct name is created, but outside of the directory that i want it in.
Ive tried running SDfindentryindirectory, with sdentrynames pointed at my sub name, and I get an SDstatus response of 48, so it is finding the correct sub name- which means I now should have all the data I need to write the file ?
How do i delete a file, but leave the directory entry? Some pointers (or even a routine?) would help.
As part of reliablity testig of a new boartd - I have set a loop writing a new file name, appending 1000 lines of text to the file, then creating a new file name etc etc. It runs over night OK without crashing, but I notive that once 16 files have been written, the last file ( file 16) always gets overwritten? Does this mean that in the root, i can only have 16 file names, or is it beacsue I need to incr the sector number?
Do you have any guidance as to what to do after a bad read or write. I can deliberately create a bad write
regards
neil _________________ Neil |
|
Back to top |
|
|
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Fri Jul 08, 2011 7:20 am Post subject: |
|
|
easily enough, but coding out of it without manual intervention is what I need to do.
regards
neil _________________ Neil |
|
Back to top |
|
|
KokkeKat
Joined: 08 May 2011 Posts: 59 Location: Stockholm
|
Posted: Fri Jul 08, 2011 12:10 pm Post subject: |
|
|
Hi Neil
Please see the comments for Sdcreatefileordir in "KokkeKat_FAT-free_SD_lib_code.bas". Here it says (among other things):
' Input variables:
' Sdstartdirclusterd = the directory cluster number (in which the file or subdirectory should be created). Set to 0 for root directory.
' (and more)
So, before starting to create a file or subdirectory, you need to make sure that a number of variables are set (including the fsinfo variables). From the beginning of "Example_WRITE_FILE.bas":
' Create and write to the file
Sdentrynames = "138 TXT"
Sdyear = 2011
Sdmonth = 2
Sdday = 16
Sdhours = 00
Sdminutes = 30
Sdseconds = 32
Gosub Sdreadfsinfo
Sdcreatemode = 0 ' Create file
Sdstartdirclusterd = 0
Gosub Sdcreatefileordir ' Find free FAT entry, find free directory entry, and save the directory entry back to the SD card
' And so on
---
You therefore need to assign sdstartdirclusterd = [the first cluster number of the directory in which you want the file to be created]. This value can typically be found in one of the (output) variables from your preceding processing step (or it could be "0" for root). My previously given advice to use "sdstartdirclusterd = sdfatclusterd" could be case specific, so you need to look in the code to make sure that you are assigning the proper variable.
Routine Sdcreatefileordir internally calls Sdfindfreefat, that has Sdfatclusterd as an output variable. It contains the cluster number in which the new file or subdirectory will start. In the previous example, you are first creating a new subdirectory in root and then creating a new file in that subdirectory, so Sdfatclusterd will be set.
===
I have to go now, but I will return later.
Kind regards
Niclas |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|