Shop OBEX P1 Docs P2 Docs Learn Events
FSRW handshaking with write command — Parallax Forums

FSRW handshaking with write command

StevenRStevenR Posts: 13
edited 2010-01-25 16:06 in Propeller 1
Is there a command to find out if the block of data written to the SD card was successful?

For example I am using:

sd.pwrite(@block,256)


What would be the next line of code to confirm the write?

tnx,

Steven.

Comments

  • MagIO2MagIO2 Posts: 2,243
    edited 2010-01-23 22:18
    pwrite will write into a local buffer first. So depending on how much bytes are already filled it won't write to the SD card at all. You can check the result of pwrite. If it's negative something went wrong.
    But if it's positive you can''t tell if it's already written to the card or if only the copy to the buffer was OK.
  • David BDavid B Posts: 592
    edited 2010-01-24 01:34
    If your project could write 512 byte sectors of data to the card, you could go directly to the underlying SD-sector-driver code, which aborts on error.

    I haven't used it to directly write to a card, but here's an example of reading a sector from a card. This example reads sector zero from an SD card and displays the FAT boot MBR signature "55AA".

    By byte-misaligning the buffer, this demonstrates forcing an abort error, then capturing and displaying the error code (-4 is "misaligned buffer") This can also ask for an address out-of-range, causing the routine to return "-64".

    I assume that the underlying SD-access code similarly attempts to capture and report write errors, which would answer your question, but I don't understand the SD access code enough to say for sure that it does that.


    
    CON
    
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000   
    
      SD_CS      = 24
      SD_DI      = 25
      SD_CK      = 26     
      SD_DO      = 27
        
    OBJ
    
      lcd:    "proto_lcd"
      sdcard: "mb_rawb_spi"
        
    VAR
      
    '  byte force_align_error
      byte buffer[noparse][[/noparse]512]
      
                
    PUB main | type, signature, status, address
      
      lcd.init
    
      address := 0  ' $FFF_FFFF
    
      type := sdcard.start_explicit(SD_DO, SD_CK, SD_DI, SD_CS)
      status := \sdcard.readblock(address, @buffer)
      sdcard.stop
    
      if status < 0
        lcd.str1x(String("SD error: "), -status, 6)
        repeat
    
      signature := buffer[noparse][[/noparse]510] << 8 + buffer[noparse][[/noparse]511]
              
      lcd.str1x(String("type: "), type, 8)        ' 00000002 on SD card                               
      lcd.str2x(String("Sign: "), signature, 8)   ' 000055AA on FAT-formatted SD card
      repeat
    
    
    
  • StevenRStevenR Posts: 13
    edited 2010-01-25 05:25
    I just tried to successively write blocks of 512 bytes and only the first 512 bytes of the 50k byte stream were written to the card.

    In the interest of science, I just tried to write 1024 byte blocks. Again only the first 512 bytes were written to the card.

    In the further interest of science, I wrote one byte at a time and the card only took the first 512 writes.

    What is limiting the writes to 512 bytes?
  • rokickirokicki Posts: 1,000
    edited 2010-01-25 07:01
    Just call pflush(). This will ensure *every* byte is written to the card.
    (You should pause up to about 1/2 second after the call, because the
    card might, under extreme circumstances take that long to actually
    write the buffer it was sent). If you need confirmation, just do
    anything that forces a read (like trying to open a non-existent file,
    which will also close the existing file).

    In general, just call pflush() and you should be just fine, unless your
    program controls power and you will be immediately powering off.

    Note that calling pflush() can seriously slow things down. If you
    pflush() every byte, for instance, I wouldn't be surprised if things
    are 10,000 slower than normal.

    In general, you should pclose() after writes. If you don't pclose()
    after writes, then yes, you should pflush() if you think someone
    might eject the card, or the program might stop or run out of
    power before then. If you do not pclose(), or pflush(),
    the data will in general *not* be written to the card (or more
    accurately, it will be, but the updated metadata won't be).

    Perhaps you might want to explain more about what you are
    doing, and we can give you some good advice?

    -tom
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-01-25 08:47
    pflushing is not only slower, it also wears out the SD card much faster. Say you write single longs to the SD card and flush after each one. That makes 64 write accesses to one sector compared to one write if you do it sector-wise. (What about updates of the directory? Is the size updated by FSRW? In that case the situation for the directory sectors is even worse!)

    From this point of view you should maybe think about how ugent it is to have each long logged or if you can efford to loose up to 64 longs. (Maybe one write is doing more than a long, then you'll loose less entries in your case)

    FSRW is pretty stable and I never had a problem with loosing sectors. You should post your code.
  • StevenRStevenR Posts: 13
    edited 2010-01-25 15:23
    I will have to wait until this evening to post my code but it is pretty simple.

    Here is some pseudo code of what I am trying to accomplish:


    Read a byte from the serial port

    Store byte into array

    If 512 bytes have been stored in array then

    sd.prwite array to card

    Else get another byte from the serial port

    If end of byte stream from serial port then

    sd.pclose

    Else get another 512 bytes from serial port


    Perhaps someone could post some code of their own to make this work.

    tnx,

    Steven.

    Post Edited (StevenR) : 1/25/2010 3:30:20 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2010-01-25 15:41
    Perhaps you could post your own actual code rather than pseudo-code. What you posted looks like it ought to work, so there must be something wrong with your actual code. The best was to post Spin code is to use the "Post Reply" button and the Attachment Manager that appears with the message entry window. That way you can upload your actual source file.
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-01-25 16:06
    What might be wrong with this pseudo-code is, that the "if end of bytestream" might have to write what's been collected in between the last write before closing. You know what I mean?

    Say you received 700 bytes.
    After 512 you write.
    After another 188 you find the end of bytestream condition is true and you close the file.
    But you did not write that 188 bytes.

    But maybe your pseudo code is not what you really do.
Sign In or Register to comment.