> > I can confirm that a few fixes in v2.1 were missing, so trunk works
> > correctly, didn't you forget to rebuild the kernel when building trunk ?
> > Attached is a patch to v2.1 that contain the fixes backported from
> > trunk. Please try this patch and tell me if this works for you.
> >
> In fact, I've downloaded the last version of trunk before your mail and
> the patch. You're right that works pretty good with this version... :)
>
> Unfortunately, it seem's that we can't share between a real time process
> and a non real one ?
Sharing memory should work, could you explain what happens ? Note that
you may use Linux regular shared memory services in the real-time
process by calling __real_shm_open instead of shm_open.
Ok,
But I'd like a real time behaviour of shared memory for my real time
task... so I can't use __real_shm_open, etc...
Here is the little code I've developped to access shared memory. May be
there some mistakes...
I compile it with or without xeno-config --posix-cflags, xeno-config
--posix-ldflags to get two executables.
I launch these two executables and the shared_memory seem's to be
different in these two cases.
All Xenomai processes are accessing the same shared_memory while all
non-xenomai processes are accessing another one shared memory.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <pthread.h>
#include <errno.h>
#include "rtsharedmem.h"
/* **********************************************************************
* Creates a shared memory object protected by a mutex *
* This object is referenced throw its name. If there's no *
* shared memory object with the given name, a new one is created, *
* otherwise, we get an access to the existing shared memory object. *
************************************************************************/
MemMap* RtOpenSharedMem(unsigned int nbvalues, const char * name) {
int shm_exists;
int h_shm;
MemMap* mem;
void * ptr;
int * nbaccess;
char *name_shm;
name_shm = (char *)malloc((strlen(name)+6)*sizeof(char));
mem = (MemMap *)malloc(sizeof(MemMap));
shm_exists = 0;
strcpy(name_shm, name);
sprintf(name_shm, "/%s_shm", name);
/* Here is the clean version to open shm, but for the moment, this
doesn't work with xenomai.*/
h_shm = shm_open( name_shm, O_RDWR | O_CREAT | O_EXCL, S_IRUSR |
S_IWUSR | S_IROTH | S_IWOTH);
if (h_shm < 0)
{
if (errno == EEXIST)
{
/* shm_open has just warned that shm already exists */
/* we shouldn't need O_CREAT here but xenomain failed
without */
h_shm = shm_open( name_shm, O_RDWR| O_CREAT, S_IRUSR |
S_IWUSR | S_IROTH | S_IWOTH);
if (h_shm<0)
{
printf("shm_open failed to open existing shared
mem : %s\n", name_shm);
return NULL;
}
shm_exists = 1;
}
else
{
/* shm_open really failed */
printf("shm_open failed to open %s\n", name_shm);
return NULL;
}
}
// /* the following lines shouldn't be commented but xenomai... */
// else
// {
// /* a new shm_file has been created, we need to truncate it */
// if (ftruncate(h_shm, nbvalues * sizeof(double))==-1)
// {
// printf("truncate failed\n");
// goto close_and_unlink;
// }
// }
if (ftruncate(h_shm, nbvalues * sizeof(double))==-1)
{
printf("truncate failed\n");
goto close_and_unlink;
}
ptr = mmap(NULL, sizeof(int) + nbvalues * sizeof(double), PROT_READ |
PROT_WRITE, MAP_SHARED, h_shm, 0);
if( ptr == MAP_FAILED) {
printf("mmap failed\n");
goto close_and_unlink;
}
mem->h_mut = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
pthread_mutex_init(mem->h_mut, NULL);
/* the first sizeof(int) bytes at ptr are reserved to count the number
of access to shared mem
in order to be able to unlink cleanly */
nbaccess = (int *)ptr;
if (shm_exists)
*nbaccess = (*nbaccess)+1;
else
*nbaccess = 1;
/* the real data starts at ptr + sizeof(int) */
mem->ptr = (double *)(ptr + sizeof(int));
mem->h_shm = h_shm;
mem->nbvalues = nbvalues;
mem->name_shm = name_shm;
return mem;
close_and_unlink:
close(h_shm);
if (shm_exists==0)
shm_unlink(name_shm);
free(name_shm);
free(mem);
return NULL;
}
/****************************************************************
* Write datas to the shared memory after getting the mutex*
****************************************************************/
int RtWriteSharedMem(MemMap * shared_mem, const double * data) {
if(pthread_mutex_lock(shared_mem->h_mut)!=0)
return -1;
memcpy(shared_mem->ptr, data, shared_mem->nbvalues * (sizeof(double)) );
if (pthread_mutex_unlock(shared_mem->h_mut)!=0)
return -1;
return 0;
}
/****************************************************************
* Read datas from the shared memory and copy it to data *
****************************************************************/
int RtReadSharedMem(double * data, const MemMap * shared_mem) {
if(pthread_mutex_lock(shared_mem->h_mut)!=0)
return -1;
memcpy(data, shared_mem->ptr, shared_mem->nbvalues * (sizeof(double)) );
if (pthread_mutex_unlock(shared_mem->h_mut)!=0)
return -1;
return 0;
}
/****************************************************************
* Close shared memory : no further access can't be done. *
* Memory allocated in RtOpenSharedMem is freed. *
****************************************************************/
int RtCloseSharedMem(MemMap * shared_mem) {
void *ptr;
int *ptr_nbaccess;
int int_nbaccess;
if (shared_mem == NULL)
return -1;
if (pthread_mutex_lock(shared_mem->h_mut)!=0)
return -1;
/* the sizeof(int) bytes before shared_mem->ptr count the number of
access to shared memory */
ptr = shared_mem->ptr - sizeof(int);
ptr_nbaccess = (int *)ptr;
*ptr_nbaccess = *ptr_nbaccess - 1;
int_nbaccess = *ptr_nbaccess;
// printf("number of access %d\n", int_nbaccess);
if (munmap(ptr, sizeof(int) + shared_mem->nbvalues * sizeof(double))!=0)
return -1;
if (close(shared_mem->h_shm)!=0)
return -1;
if (pthread_mutex_unlock(shared_mem->h_mut)!=0)
return -1;
if (pthread_mutex_destroy(shared_mem->h_mut)!=0)
return -1;
if (int_nbaccess == 0) /* that was the last process to access this
shared mem */
shm_unlink(shared_mem->name_shm);
free(shared_mem->name_shm);
free(shared_mem);
shared_mem = NULL;
return 0;
}
#ifndef __RTSHAREDMEM_H__
#define __RTSHAREDMEM_H__
#include <pthread.h>
typedef struct {
void *ptr;
int h_shm;
pthread_mutex_t *h_mut;
char * name_shm;
char * name_mut;
unsigned int nbvalues;
} MemMap;
MemMap* RtOpenSharedMem(unsigned int nbvalues, const char * name);
int RtWriteSharedMem(MemMap * shared_mem, const double * data);
int RtReadSharedMem(double * data, const MemMap * shared_mem);
int RtCloseSharedMem(MemMap * shared_mem);
#endif // __RTSHAREDMEM_H__
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>
#include "rttimer.h"
#include "rtsharedmem.h"
#define NANOCOEF 0.000000001
int RtSetAsPriorityTask()
{
struct sched_param mysched;
mlockall(MCL_CURRENT | MCL_FUTURE);
mysched.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1;
pthread_setschedparam( pthread_self(), SCHED_FIFO, &mysched);
return 0;
}
void RtWaitFor(double time) {
struct timespec rqtp, rmtp;
rqtp.tv_sec = (time_t)time;
rqtp.tv_nsec = (long) ( ( time - (double)(rqtp.tv_sec) ) / NANOCOEF );
nanosleep(&rqtp, &rmtp);
}
int main(int argc, char * argv[])
{
MemMap *mem;
double *data, *val;
RtSetAsPriorityTask();
data = (double *)calloc(1, sizeof(double));
val = (double *)malloc(sizeof(double));
if (argc==1)
*val = 1.0;
else
*val = atof(argv[1]);
//printf("EACCES %d, EFAULT %d, EFBIG %d, EINTR %d, EINVAL %d, EIO %d,
EISDIR %d, ELOOP %d, ENAMETOOLONG %d, ENOENT %d, ENOTDIR %d, EROFS %d, ETXTBSY
%d, EBADF %d\n", EACCES, EFAULT, EFBIG, EINTR, EINVAL, EIO, EISDIR, ELOOP,
ENAMETOOLONG, ENOENT, ENOTDIR, EROFS, ETXTBSY, EBADF);
mem = RtOpenSharedMem(1, "shared1");
if (mem == NULL)
{
printf("ERRNO %d\n", errno);
perror("RtOpenSharedMem");
return -1;
}
printf("data written\t%lf\n", ((double *)(val))[0]);
fflush(stdout);
if (RtWriteSharedMem(mem, (double *)val)<0)
{
perror("RtWriteSharedMem");
return -1;
}
RtWaitFor(1.0);
if (RtReadSharedMem(data, mem)<0)
{
perror("RtReadSharedMem");
return -1;
}
printf("data read\t%lf\n", data[0]);
fflush(stdout);
if (RtCloseSharedMem(mem)<0)
{
perror("RtCloseSharedMem");
return -1;
}
return 0;
}
_______________________________________________
Xenomai-help mailing list
Xenomai-help@gna.org
https://mail.gna.org/listinfo/xenomai-help