-
Notifications
You must be signed in to change notification settings - Fork 76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to do multi-block writes? #124
Comments
In my own fork I have been playing with creating an array of 1 : Data from existing block
- : Input buffer to write
0 : Zeroed blank data
owned slice slice owned
|1111|----|---------|---------|----|0000|
| block 0 | block 1 | block 2 | block 3 | Block 0 and block 3 would in this case need to be owned, since they must be constructed partially from some of the input buffer, and in the case of block 0, some previously written data. Block 1 and block 2 can be constructed as a 512-byte slice of the input buffer, without copying anything. So in any case, we only need to create two owned blocks, and the rest can be referenced from the input buffer, and all could be turned into a series of |
I think the trick is ensuring any byte slices which are passed straight to the disk API as if they were Blocks are aligned as a Block would be. But yes if the input is correctly aligned and is at least 512 bytes, a memcpy could be avoided. Or I guess more importantly, a multi-block write could be sent to the SD Card. I believe the README says that this crate chooses readability over performance, but this is, I think, a sensible optimisation for most scenarios. Although not on the nRF line where DMA requires data to be in RAM and passing along slices supplied by a user means it's possible to pass in a slice located in flash. But the nRF HAL gets to deal with that. |
Another option is a feature which enables the VolumeManager to hold a 4K internal buffer instead of a 512 byte one. User data alignment then doesn't matter, and we can send eight blocks at a time to the disk. |
I like the idea of the 4K buffer, since that is essentially what I have ended up doing external to this library. If the entire buffer could be handled internally, ensuring optimal alignment, that would be really nice. Though shouldn't it be each File (or RawFile) which should hold an internal buffer? |
So far, I've had one buffer that the files and FAT32 code can temporarily access. This is designed for microcontrollers with like 8K of RAM total. |
A BufferedFile object, would be a cool, but different thing. |
How would that work? If you have multiple files open, that are all being written to, wouldn't the buffer get filled with data from different sources? Would you then write the buffer contents, which contains data from file A, whenever file B wants to write? |
Because every disk write is either a complete block, so the prior contents are overwritten, or a read/modify/write. There is no file buffering. If you call |
I am aware of that, maybe I misunderstood your previous statement. Hmm, are there any parts of the library, except from I guess what I would really want for my project is the |
I recall thinking that the VolumeManager might be statically allocated, saving you precious stack space. |
I feel like I am missing something here, but are multi-block writes not possible through the public API?
SdCardInner::write(..)
seems to have the support for writing multiple blocks properly, but all the calling functions (specifically the publicVolumeManager::write()
) seem to just use a single[Block::new()]
multiple times, instead of an actual multi-element array ofBlock
. Is this correct?The text was updated successfully, but these errors were encountered: