Double buffering for SD card
Graham Stabler
Posts: 2,510
I'm using the propeller for some data capture and have problems with the delay caused by writing, I'm using rokicki's code and from what I can tell fsrw has a buffer called buf, you fill it using pwrite and once full it is flushed. The flushing is done by the cog running the assembly however I want to be able to double buffer so that while writing I can carry on filling the buffer. What I did do is create a 1024 byte buffer and once half full I would pwrite the first half and when completely full I would pwrite the second half. but pwriting 512bytes first copies it in to buf and this is a considerable delay.
I really want my double buffer to live in fsrw, I think I can code this but wanted to check I have not got something horribly wrong.
Cheers,
Graham
I really want my double buffer to live in fsrw, I think I can code this but wanted to check I have not got something horribly wrong.
Cheers,
Graham
Comments
Jonathan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lonesock
Piranha are people too.
(geek humor escalation => "There are 100 types of people: those who understand binary, and those who understand bit masks")
But looking at the code it does not look as if it will work for me, I need to carry on filling my buffer while the data is being written, the whole reason for having the card is because I can't allocate sufficient memory and I want to be able to fill with card with data if I need to.
When I call pwrite it moves one buffer in hub ram to another in hub ram before writing so in that time I cannot fill my buffer. If however buf was twice as long I could use that as my buffer and pwrite would just call the flush program. Even then the code waits for the write to be complete from what I can tell in sdspiqasm and that occasionally seems to take longer than other times.
As I said I may have missed the point completely but it seems I can'd find a way to keep filling my buffer while the card is being written to.
Graham
You can find out the start sector of the file by an easy modification of popen. You only have to return the datasector as far as I remember.
Of course you then have to keep track of the file-pointer by yourself (how many bytes have been written). Maybe you could use a background COG wich writes the file-pointer to EEPROM? Or your can make sure that the data is always different from $0000_0000 and then you know whenever you find that in the file you look at the end of the data.
Graham
Jonathan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lonesock
Piranha are people too.
(geek humor escalation => "There are 100 types of people: those who understand binary, and those who understand bit masks")
It would seem that if I call this function with the address to my 512byte buffer it will copy it into buf and that is in hub ram. Only once buf is full will it call pflushbuf which in turn calls writeblock and I assume the assembly code reads the 512b from hub ram.
Graham
If you don't care about the FAT32/16 file system, you can just hijack the block driver for the fastest possible writes, as long as you only need to write 512 bytes at a time. (You can get almost 2MB/s write speeds this way.) You could even pre-create a contiguous "null-file" of all zeros, then use the block layer to sequentially overwrite the data in the null-file.
Jonathan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lonesock
Piranha are people too.
(geek humor escalation => "There are 100 types of people: those who understand binary, and those who understand bit masks")
This gets rid of the delay I got every 512bytes written but there is still an occasional delay of 0.25 seconds which seems to take place in sdspiqasm so I assume it is something to do with the card or the file system.
I like the idea of a zeroed file but I don't really get the way everything works so I'm not sure how to do it and like usual I'm trying to get something working at the last minute.
Graham
I haven't started to track down the cause but if I don't find the source it may be a serious limiter for my project...if anyone on this thread knows or has a theory regarding what might be the cause of these sporadic delays please chime in...My first guess is that the SD card needs to erase its bits (set to all 1s?) before writing to them and so on occasion needs to do some house cleaning on a block of memory...this seems to be a sketchy theory but then again SD card inner workings are unfamiliar to me.
Jonathan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lonesock
Piranha are people too.
(geek humor escalation => "There are 100 types of people: those who understand binary, and those who understand bit masks")
At what rate are you filling your buffer?
I've done a lot of work with FSRW and datalogging. I've found to get maximum speed without dropping consecutive samples, or having larger but occasional gaps in the data I had to setup a buffer that was nearly .5 seconds long. I can give you more specifics tomorrow, but if you give a ballpark of what rate you are trying to capture I may be able to help.
A long time ago, Rokicki told me that when using FSRW (with file system layer) you need a buffer that can absorb ~.33 seconds of data. Every once in a while the filesystem layer does something that can take this long. If that's really not acceptable you'll need to move to the block layer...
I was able to do 5000 bytes/second continuous by creating a circular buffer with 1 second worth of space. If you have the space available, I think it's a straight forward way to gain speed.
p
Graham
1. Double the size of buf
2. Add a function to put data directly in to buf (in my case longs)
3. Add a function to call a modified version of pflushbuf with an offset (equal to 0 or 512bytes) so I can write first or second half of buf
4. Modified version of pflushbuf does block write to @buf + offset and calls modified version of blockwrite
5 modified blockwrite (only used when I am writing my data) has the wait for command to be clear removed.
So I think this will work as long as you do not try to write more than 512bytes every 0.12 ish seconds. This is OK for this application but I will definitely investigate having empty files to fill for the future to boost the speed further.
Cheers,
Graham