Concurrent SD card access
ke4pjw
Posts: 1,155
in Propeller 2
Has anyone been able to access the SD card via two separate cogs at the same time? For example both cogs read the same file, but at different positions in the file?
Thanks,
Terry
Comments
Bound to be a fail. At the very least the SD card will get confused. What should work, though, is operating two separate cards at once.
PS: That's the job of an OS. To deal with multiple tasks wanting access to multiples files from the one shared filesystem.
I think I have a workaround. It just requires a little book keeping in my specific use case. If the SD card objects supported file handles, then it could do the book keeping. A full blowen OS doesn't need to be written to do this. I have locks that manage multiple cogs accessing the Wiznet chip. No OS needed.
FAT32 has a seek function:
fileSeek(position)
That might let you jump around inside the same file...
If the SD card application is read only and you take/give a lock between sector accesses from different COGs you should be able to share reads from two or more COGs. However as soon as you introduce writes you'd then need to be mindful about filesystem structures and exactly where your lock/unlock points are so you don't clobber the files with two writes to the same sector or otherwise read stale data etc.
This is exactly what I am going to have to do, though I didn't think of just keeping the file open. In this specific case, that works.
I wonder if a wrapper can be written to do file handles. The wrapper could keep track of files that are "opened", the mode they were opened in, their file position, and prevent a single file from being opened for writing by two "processes". The wrapper would have to open and close the files upon each access, have the bookkeeping in hubram, and use locks to ensure only one COG has access. Access times might not be great. This would lend itself to having a webserver that has more than 1 available port and multiple threads in separate cogs.
At the moment, this is all a thought exercise. I think it might be useful.
OK, I think a wrapper is doable. And the great thing about doing it as a wrapper, you can easily swap out the engine if another one comes along.
Of course you can certainly code such functionality that doesn't yet exist. Yes, the locks are a minimum.
2 cogs + 1 SD card = trouble
A driver for the card is needed, something like PSRAM driver, so one cog controls the SD and responds to requests from other cogs.
Depending on the processing load for those cogs, you could run one cog with a sequence of:
process own cog SD request
process own cog web server code
process other cog SD request
It would probably be a bit slower than using 3 cogs, but if you are short on cogs…
Edit: I suppose you could also have one cog running the driver and the other serving both web sessions if there’s enough cog ram in the web server cog to hold the pointers to the buffers for both sessions.
I started on a filesystem wrapper that provides filehandles and things are progressing. I think this might be useful for others.
Quick and dirty test of open.
Probably not what you are after, but Catalina can do this - i.e. you can start C functions in different cogs and each cog can then open and read from a file - either the same file or a different file.
Here is an example I just compiled and ran (it's a modified version of the multiple_cogs.c demo, and uses the utility functions from the demos\multicog folder).
This version only has one cog accessing the file at any one time, but if multiple cogs may do so, just use a lock to prevent contention (you could use the same lock as is used to prevent contention on the serial port).
Attached is my wrapper for concurrent SD card access. When you open a file, it returns a filehandle. All operations will need to provide that file handle to read and write to the file. The methods in this object map to Nyamekye's FAT32 object, but it could be modified to support other filesystem objects.
ToDos:
I will develop this further as needed. Currently it is used in my April Fools gag, and seems to work OK. Performance is not great, but it does work.
--Terry