Shop OBEX P1 Docs P2 Docs Learn Events
SD Card File Copy - How to copy a file to another - CODE POSTED — Parallax Forums

SD Card File Copy - How to copy a file to another - CODE POSTED

Paul_HPaul_H Posts: 85
edited 2008-06-01 22:13 in Propeller 1
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

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2008-05-13 22:38
    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_mantpw_man Posts: 276
    edited 2008-05-13 22:41
    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
    tongue.gif
  • mparkmpark Posts: 1,305
    edited 2008-05-13 23:08
    Hey tpw_man, did you just have a birthday?

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

    PS, BTW, and FYI:
    To search the forum, use search.parallax.com (do not use the Search button).
    Check out the Propeller Wiki: propeller.wikispaces.com/
  • rokickirokicki Posts: 1,000
    edited 2008-05-13 23:24
    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 GreenMike Green Posts: 23,101
    edited 2008-05-13 23:58
    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_HPaul_H Posts: 85
    edited 2008-05-14 01:01
    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... smile.gif

    Thanks,
    Paul
  • Paul_HPaul_H Posts: 85
    edited 2008-05-24 03:23
    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[noparse][[/noparse]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[noparse][[/noparse]idx] := sdfat.pgetc                         ' current interesting character
          if datum[noparse][[/noparse]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[noparse][[/noparse]idx] < 0                                 ' check for end of file(NULL)
            quit                                            ' abort loop on EOF
          if datum[noparse][[/noparse]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[noparse][[/noparse]idx])                           ' copy char out
          idx++                                             ' increment array pointer
        sdfat.pclose                                        ' close dst
        
        loop++                                              ' get next N bytes from SRC file
    
        if datum[noparse][[/noparse]idx] < 0                                   ' check for end of file(NULL)
          quit
        if datum[noparse][[/noparse]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! "))
    
    
    
  • vampyrevampyre Posts: 146
    edited 2008-05-24 11:27
    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_HPaul_H Posts: 85
    edited 2008-05-24 17:37
    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
  • vampyrevampyre Posts: 146
    edited 2008-05-24 22:34
    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 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_HPaul_H Posts: 85
    edited 2008-06-01 22:13
    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
Sign In or Register to comment.