PDA

View Full Version : SD Card File Copy - How to copy a file to another - CODE POSTED



Paul_H
05-14-2008, 04:07 AM
Check below for my SDFileCopy.ZIP code. You need to rename back to .zip.
Paul


---------------
Hi All,

Here's a question regarding SD Card file copies. I'm using Tom Rokicki's SD programs (thank you Tom) and want to copy one existing file into another. However I can only open one file at a time ( or that is what I have been successful with!)

So procedurally, I could open the SRC file, copy a number of Longs to memory, close the original, then open my DEST file and copy in from memory, close it, and repeat. However this means I need to keep track of where I was in the SRC file for consecutive reads.

Is there any more direct method to solve this problem - like opening 2 files at once and copying directly, or have I described the most direct path of sequentially opening the files?
Thanks for the advice!

Paul

Post Edited (Paul_H) : 5/24/2008 3:27:53 AM GMT

Mike Green
05-14-2008, 05:38 AM
There really isn't a direct way to do this other than to modify the routines to allow more than one file to be open at a time. If your input file is allocated all in one extent, you could add a routine to the object to check for a single extent and return the starting sector number and number of sectors, then close the input file and open the output file, then read the input file using the low level SD card routines and the information from the input file extent while writing the output file with the high level routines.

tpw_man
05-14-2008, 05:41 AM
You can probably just add a routine that changes the variable "floc" to the position you want to go to in the file and fill the buffer back up with pfillbuff. I am in the process of trying it, but I am away from my Propeller right now :-(

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
I am 1011, so be surprised!


Advertisement sponsored by dfletch:
Come and join us on the Propeller IRC channel for fast and easy help!
Channel: #propeller
Server: irc.freenode.net or freenode.net
If you don't want to bother installing an IRC client, use Mibbit. www.mibbit.com (http://www.mibbit.com)
http://forums.parallax.com/images/smilies/tongue.gif

mpark
05-14-2008, 06:08 AM
Hey tpw_man, did you just have a birthday?

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Michael Park

PS, BTW, and FYI:
To search the forum, use search.parallax.com (http://search.parallax.com) (do not use the Search button).
Check out the Propeller Wiki: propeller.wikispaces.com/ (http://propeller.wikispaces.com/)

rokicki
05-14-2008, 06:24 AM
Yeah, the best way is to just use a modified version that allows multiple files open at a time.

I think someone started this. I do not know how far along they got. I'll have to do some
looking and see if I can find who was going to do this.

There are all sorts of hacky solutions possible, but I'd avoid them.

Maybe I'll spend a bit of time and support multiple files. That shouldn't be too hard. (There
are some tricky parts, though, like making sure the same file is not opened twice, or if we
need to support that, then making sure the data between the two stays in sync. Easiest for
now is just making sure if more than one file is open that it is not one of the other files
already open.)

Of course as soon as I release it someone will use it to open two separate files from
two separate cogs, and trash their filesystem. So I'll need to either protect the routines
using an appropriate mutex, or else add some other code to check this doesn't happen.

Mike Green
05-14-2008, 06:58 AM
I had started on this, but ran into some bugs and had to shelve it as other things took priority. I won't have much time to work on it until the end of July. The idea was to have a shared block buffer for FAT accesses, then an instance buffer for the actual directory searches and file access. I had also added provisions for random file positioning and update in place. I think what got me confused was the different kinds of file pointers. Some were absolute block numbers, some were relative to the FAT and directory, some were cluster numbers and block offsets, some were absolute file addresses, etc. Anyway, I'll have a lot more time to work on it in August. If anyone wants a snapshot of this "work in progress", send me a PM. I'd be happy to share. It does seem to corrupt the FAT and directory much too often.

Paul_H
05-14-2008, 08:01 AM
You guys are way over my head - and I am so thankful you are here !!

I am reading that the best answer for me may to open, read1, remember loc1, close1, open2 write2 close2, lather rinse, and repeat ...
I will investigate - thanks.

@tpw_man - if your idea does work, please post. And Happy BDay - I remember when your sig was only 1010... http://forums.parallax.com/images/smilies/smile.gif

Thanks,
Paul

Paul_H
05-24-2008, 10:23 AM
ALL,
I was able to create an ugly but working SD card copy routine. Rename attached to zip for the SPIN files, or copy the following text.

As it is now, there is a LOT of opening and closing of files as it loops through the SRC data file and keeping its place. I have not yet messed with the FLOC pointer but that may speed things up.
Until I figure it out, Please enjoy, and post your thoughts.

Thanks!
Paul




{
* SD File Copy
* Author: Paul Hubner

* This SPIN routine copies data from one SDCard file to a second.
* It is currently slow because it can only address one SDCard file at a time and
* looses alot of cycles reopening and reclosing the files.
*
}
CON

_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
_stack = 48

' PIN ASSIGNMENTS
' NAME PIN# / VALUE
' ---------- -----------------

' SDCard Assignments
SDbase = 00 ' SD Card base pin, 4 total
'01
'02
'03

' Video Output Assignments
TVBase = 12 ' TV base pin

VAR
byte s,d,datum[64] ' space for file copying

OBJ
tv : "tv_text" ' TV video output driver
sdfat : "fsrw" ' FAT16 object for SD card logger

PUB start

''Initialize all necessary routines into their cogs as appropriate

tv.start(TVBase) ' start TV display
sdfat.mount(SDbase) ' mount the SD card on pins P0 to P3

tv.str(string("Copying ...",13))

d := string("dest01.txt") ' define DESTINATION file
s := string("header.txt") ' define SOURCE file
CopyFile(s,d)

tv.str(string("Complete COPY...",13))
tv.out(13)
readcard(d) ' show what was written



PUB CopyFile(src,dst) | loop, N, idx
'' reads SDcard file to tv. Need to genericize ReadCard for any filename.
'' OPEN and CLOSE on file is very time intensive compared to reading and writing actual data.


N := 64 ' number of bytes to read per loop. Make sure VAR array 'datum' matches.
loop := 0 ' keep track of number of iterations
repeat ' main copy loop

sdfat.popen(src, "r") ' open SRC
repeat N * loop ' count through the file to get to where we left off last time
datum := sdfat.pgetc ' put pointer at next character location

idx := 0
repeat N
datum[idx] := sdfat.pgetc ' current interesting character
if datum[idx] < 0 ' check for end of file(NULL)
quit ' abort loop on EOF
idx++ ' increment the pointer position in the READ file
sdfat.pclose ' close src


sdfat.popen(dst, "a") ' open DST
idx := 0 ' reset index position for loop out
repeat N
if datum[idx] < 0 ' check for end of file(NULL)
quit ' abort loop on EOF
if datum[idx] == 255 ' check for end of file(255)
quit ' abort loop on 255 EOF. Not sure why it it 255 and not -1
sdfat.pputc(datum[idx]) ' copy char out
idx++ ' increment array pointer
sdfat.pclose ' close dst

loop++ ' get next N bytes from SRC file

if datum[idx] < 0 ' check for end of file(NULL)
quit
if datum[idx] == 255 ' check for end of file(255)
quit

sdfat.pclose ' close dst

PUB ReadCard(fname) | r
'' reads SDcard file to tv.
tv.str($00)
sdfat.popen(fname, "r")
tv.str(string("Opening DST: "))
tv.out(13)
repeat
r := sdfat.pgetc
if r < 0
quit
tv.out(r)
tv.out(13)
tv.str(string("Complete! "))

vampyre
05-24-2008, 06:27 PM
This is really great stuff!. I was planning on using some similar code for my operating system in the next couple of days, but looks like you've already done it. mind if i steal your code Paul?

Paul_H
05-25-2008, 12:37 AM
Go for it - thats why its here!

It is SLOW because I'm using the spin SD driver rather than the faster assembler ones, and also because I iterate through the source file everytime it is opened.

So any speed ideas are appreciate!
Paul

vampyre
05-25-2008, 05:34 AM
Thanks! I made a few alterations and slapped it into my code, which i'm gonna be uploading to my porthos thread today. Thanks a lot. It is slower than molasses in December, but its faster than the copy command i had yesterday http://forums.parallax.com/images/smilies/wink.gif I dont think i'll be trying to speed up this code, because once i get to release .05 of porthos i'll be going to work on a full featured fat32 driver port with multiple file open support. I've already got the C code, its just a matter of porting it to spin.

Paul_H
06-02-2008, 05:13 AM
Vampyre,

Glad to help - yeah I probably am not going to up the copy speed either until I have a ton of free time (aka probably never), and I only use the code once to create a KML file a before I start loggin GPS. My COPY takes about 30 sec, and I can live with it for now.

Good luck and please post your SD code whenever you get there!
Paul