I am along the way of creating a embedded C data storage module. It will likely be incorporated by files/modules who would like use of this "shared" system-wide data. Multiple tasks aggregate a large number of inputs (GPIO, CAN, I2C/SPI/SSP data, etc) and stores individuals values off while using API. Then, other tasks can access the information securely with the API. The machine is definitely an embedded application by having an RTOS, so mutexes are utilized to safeguard the information. These ideas is going to be used no matter the implementation
I have designed something similar to this previously, and I am attempting to enhance it. I am presently midway via a new implementation and I am having a couple of hiccups and would actually take advantage of a brand new perspective.
Quick rundown from the needs of the module:
Now you ask , how does one start creating something similar to this? Enumerations, structures, accessors, macros, etc? I am not searching for code here, just talking about general overall design ideas. If there is a solution on the web that addresses these kinds of things, possibly simply a hyperlink is enough.
I have been in cases like this a few occasions myself. Each time I have ended "moving my very ownInch, and that i certainly don't are afflicted by Not Invented Here (NIH) syndrome. Sometimes the area, processing turnaround time or reliability/recoverability needs simply make the least painful path.
So, instead of writing the truly amazing American novel around the subject, I'll just get rid of some ideas here, as the real question is pretty broad (but appreciate a minimum of developing an issue &lifier supplying background).
Is C++ up for grabs? Inline functions, templates, and a few of the Boost libraries may be helpful here. But I am speculating this really is straight-up C.
If you are using C99, you can at any rate use inline functions, that are one step above macros if this involves type safety.
You might like to consider using several mutexes to safeguard various areas of the information despite the fact that the updates are quick, you might like to split up the information into sections (e.g. configuration data, init data, error logging data, trace data, etc.) and provide each its very own mutex, lowering the funnel/choke points.
You might think about making all use of the information undergo a server task. All reads &lifier creates undergo an API which conveys using the server task. The server tasks pulls reads &lifier write demands so as from the queue, handles them rapidly by conntacting a RAM mirror, delivering reactions as needed (a minimum of for read demands), after which buffers data to NVM without anyone's knowledge, if required. Sounds heavyweight in comparison to simple mutexes however it has its own advantages in a few use cases. Have no idea enough regarding your application to understand if this sounds like possible.
One factor I'll say, is the thought of getting/setting with a tag (e.g. maybe a listing of enums like CONFIG_DATA, ADDRESS_DATA, etc.) has become a advance from directly addressing data (e.g. "produce the 256 bytes at address ox42000). I have seen several shops suffer great discomfort once the whole physical-addressing plan finally stops working &lifier they have to re-factor / re-design. Keep the "what" decoupled in the "how" - clients should not need to know or care where stuff is saved, how large it's, etc. (You may know all of this, sorry if that's the case, I simply view it constantly...)
One further factor. You pointed out mutexes. Watch out for priority inversion... that may make individuals "quick accesses" have a very very long time in some instances. Most kernel mutex implementations permit you to take into account this, but frequently it isn't enabled automatically. Again, sorry if this sounds like old news...