Inhalt
Topic:.OSAL_sharedMem.
The shared memory access is a concept of multiprocess operation systems: The memory is allocated process-specific with protection mechanism. Therefore any process has its own memory. A process can be killed and the memory of the whole process is freed. So no memory leaks in the time occurs. On the other side one process cannot disturb the memory of the other process.
The shared memory is the possibility to share memory between processes to simplify data exchange. The shared memory is a global operations system resource and should be handled carefully to assert running the whole system probably.
Another approach of using shared memory is: Emulation of target hardware on PC. On a target system it is possible to have a real shared memory between two (or more) processor hardware systems. This shared memory can be realized with a dual-port-memory IC, with special hardware such memory in an FPGA circuit or with direct memory access to a common memory area. To emulate this on PC, the software of the different processors may run on several processes on the same PC, and the shared memory access of the target hardware is emulated by the shared memory access with PC resources. In this manner it is possible to emulate a hardware functionality of an FPGA with another Process on PC too.
Topic:.OSAL_sharedMem..
On Linux the tho headerfiles sys/ipc.h
and sys/shm.h
are able to use. With them the operation shmget(key, size, lag)
can be performed. Another possibility is using the POSIX standard via shm_open(const char *name , int oflag , mode_t mode);
.
In Windows another approach is used: CreateFileMapping(handle, ..., size, name)
creates the shared memory and MapViewOfFile(hMapFile,..., name)
accesses an existing named shared memory.
If a shared memory should be used in a target system to emulate it on PC, then the shared memory access is often an access to a special existing memory location without creation and opening. The users software can/should contain shared memory OSAL operations (see next chapter) but there are empty for the target system implementation.
This different approaches should be organized as implementation on the OSAL layer. The users software should be independently written for that os-specific approaches.
Topic:.OSAL_sharedMem.osal.
You should add the os_sharedmem.c
to your project. Several implementations of os_sharedmem.c are available for Linux, Windows and for a simple target platform.
In the CRuntimeJavalike-sources there are arranged in the specialSources/...
directory. If you have abbreviating conditions of the operation system for example wchar_t
setting for the Visual Studio compiler (it is UTF16, instead UTF8) you can adapt this approaches with an special respectively
adapted version of os_sharedmem.c
in an own special directory.
In your user project files which will work with sharedmem you should
#include <OSAL/os_sharedmem.h>
This is a universal header which defines the interface to use. It is neither os-specific nor specific for any application.
The main part of the application should define
SharedMem_OSAL sharedmemMngData_xy = {0};
This is a static instance, of course dynamically created instances are possible. This instance manages only less data, the handle is part of them.
To create or access a shared memory part you must invoke in the initial part of the application:
MemC memLocation = os_createOrAccessSharedMem(&sharedmemMngData_xy, "name", size);
The type MemC contains the pointer and the length of the memory part. If the shared memory is not found on the operation system
with the given name, it is created. The size argument is only necessary for creation. If the shared memory is already existing
on operation system level, its size is defined already. The really size is returned in the MemC
struct. Note: The MemC
struct contains only 2 register data, so most of compilers return the struct data per value via register return (runtime
optimized).
You can check whether it is sufficient on calling
if(!os_isReadySharedMem(& sharedmemMngData_xy)) {?/*error message*/}
That routine accesses only the error
variable in the struct. An error should never occur , an error is a unexpected event. It may be possible on less system resources
or on an faulty name, you should evaluate the reason with debugging in the os-specific implementation. The user application
need not handle an error.
If you want to close your work with the shared memory (usual only on end of the application), invoke
os_closeSharedMem(& sharedmemMngData_xy);
The operation system checks the processes which uses the shared memory object and removes it if no more processes uses it.
Topic:.OSAL_sharedMem..
To work with the shared memory area you should define a struct
of data, use the same struct
in all your applications which uses that shared memory, and fill a qualified pointer:
typedef struct MySharedMemoryStruct_t { int32 signum; .... //structure of the data in sharedMem } MySharedMemoryStruct; MySharedMemoryStruct* shmem = null;
The shared memory needs data for managing it. Note: That data may be parts of a hyper struct, more ObjectOriented. Here there are shown as static.
SharedMem_OSAL sharedmemMng = {0}; //managing data
This routine tries to open an existing shared memory and checks the correct initialization:
void openMySharedmem(const char* name) { int size = sizeof(MySharedMemoryStruct); MemC memLocation = os_accessSharedMem(&sharedMemMng, name); if (os_isReadySharedMem(&sharedMemMng)) { //it is found existent, check the content: int size1 = size_MemC(memLocation); if (size1 < size) { //should be equal os_FatalError(-1, "Problem with ",size1, size); return; } shmem = PTR_MemC(memLocation, MySharedMemoryStruct); if (shmem->signmum != 0x12345678)) { os_FatalError(-1, "Problem with data ...", shmem->signum,0); return; } }
If open fails, then create and initialize the shared memory, because it may be the first process:
else { //create and init if access failes: memLocation = os_createSharedMem(&sharedMemMng, name, size); if (!os_isReadySharedMem(&sharedMemMng)) { os_FatalError(-1, "Problem with shared mem - exit\n", 0, 0); return; //abort on error } //initialize. shmem = PTR_MemC(memLocation, MySharedMemoryStruct); shmem->signum = 0x12345678; //any signum }
The invocation of os_FatalError(...)
should stop the execution of the thread or process. If the shared memory ressource does not run, the programm should not
be execute. The reason may be: Failure in the shared memory operation system adaption (to debug and search), the other process
has another data structure, version incompatibility etc. It is important to check that. If the application should run without
shared memory instead, the shmem
reference remain null
. Check it in the application!
Topic:.OSAL_sharedMem..
It is possible to use exact the same user algorithm shown in the above chapter. The ox_accessSharedMem(...)
should return the proper pointer and length to an dual port memory or somewhat, controlled by the name (checked with an if-chain).
If you have a processor which cannot properly process strings (such as DSP from Analog devices, only with word-Access), or
a processor with less footprint, this is too much unused code. The checks and invocation of os_FatalError(...)
are unnecessary. Then initialize the reference shmem
immediately with the correct value in a special initial routine. That is code only for the target then.