00001
00002
00003 struct RTLNML_HEADER
00004 {
00005 long message_type;
00006 unsigned long message_size;
00007 long first_message_count;
00008 long second_message_count;
00009 };
00010
00011 struct RTLNML
00012 {
00013 struct RTLNML_HEADER *header;
00014 void *mbuff_address;
00015 void *direct_data_pointer;
00016 void *local_pointer;
00017 int rtlnml_allocated_local_pointer;
00018 unsigned long max_message_size;
00019 int last_id_read;
00020 #if defined(rtai) || defined(linux_rtai)
00021 int key;
00022 #endif
00023 };
00024
00025 typedef struct RTLNML *rtlnml_t;
00026
00027 #if defined(rtai) || defined(linux_rtai)
00028 typedef rtlnml_t rtainml_t;
00029
00030 #ifdef rtai
00031 #include <linux/module.h>
00032 #else
00033 #include <stdlib.h>
00034 #include <unistd.h>
00035 #include <signal.h>
00036 #include <sys/types.h>
00037 #include <sys/stat.h>
00038 #include <fcntl.h>
00039 #include <sys/mman.h>
00040 #include <errno.h>
00041 #include <unistd.h>
00042 #endif
00043
00044 #include "rtai_shm.h"
00045 #endif
00046
00047 #define RTLNML_TYPEDEFED
00048 #ifdef MODULE
00049 #undef MODULE
00050 #endif
00051
00052
00053 #include "rtlnml.h"
00054
00055 #if !defined(rtlinux) && !defined(rtai)
00056 #include <stdlib.h>
00057 #endif
00058
00059
00060
00061 #ifdef NEED_LINUX_STRING_H
00062 #include <linux/string.h>
00063
00064
00065
00066
00067
00068 #endif
00069
00070 #include <string.h>
00071
00072 #if defined(rtlinux) || defined(rtai)
00073 extern void *kmalloc (unsigned long, int);
00074 extern void kfree (const void *);
00075 #endif
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 #if defined(rtlinux) || defined(HAVE_RTL)
00093 #include <linux/types.h>
00094 #include <linux/fs.h>
00095 #include <unistd.h>
00096 #include <fcntl.h>
00097 #include <string.h>
00098 #include <sys/mman.h>
00099 #include <sys/types.h>
00100 #include <sys/stat.h>
00101 #ifndef rtlinux_2_2
00102 #define inline static inline
00103 #endif
00104 #include "mbuff.h"
00105 #ifndef rtlinux_2_2
00106 #undef inline
00107 #endif
00108 #endif
00109
00110
00111
00112
00113 void
00114 rtlnml_init (void)
00115 {
00116 }
00117
00118 static inline void *
00119 rtlnml_malloc (unsigned long sz)
00120 {
00121 #if defined(rtlinux) || defined(rtai)
00122 return ((void *) kmalloc (sz, 1));
00123 #else
00124 return malloc (sz);
00125 #endif
00126 }
00127
00128 static inline void
00129 rtlnml_free (void *p)
00130 {
00131 #if defined(rtlinux) || defined(rtai)
00132 kfree (p);
00133 #else
00134 free (p);
00135 #endif
00136 }
00137
00138
00139
00140
00141
00142
00143 #if !defined(rtai) && !defined(linux_rtai)
00144 rtlnml_t
00145 rtlnml_open (const char *name,
00146 const char *processname,
00147 const char *filename,
00148 unsigned long size,
00149 int master)
00150 #else
00151 rtainml_t
00152 rtainml_open (const char *name,
00153 const char *processname,
00154 const char *filename,
00155 unsigned long size,
00156 int master, int key)
00157 #endif
00158 {
00159 int i;
00160 struct RTLNML *r = NULL;
00161
00162 r = (struct RTLNML *) rtlnml_malloc (sizeof (struct RTLNML));
00163 if (NULL == r)
00164 {
00165 return NULL;
00166 }
00167 r->header = NULL;
00168 r->mbuff_address = NULL;
00169 r->direct_data_pointer = NULL;
00170 r->local_pointer = NULL;
00171 r->rtlnml_allocated_local_pointer = 0;
00172 r->max_message_size = 0;
00173 r->last_id_read = 0;
00174
00175 #ifdef rtai
00176 r->mbuff_address = rtai_kmalloc (key, size + 16);
00177 r->key = key;
00178 #else
00179 #ifdef linux_rtai
00180 r->mbuff_address = rtai_malloc (key, size + 16);
00181 r->key = key;
00182 #else
00183 r->mbuff_address = mbuff_alloc (name, size + 16);
00184 #endif
00185 #endif
00186 if (NULL == r->mbuff_address)
00187 {
00188 rtlnml_free (r);
00189 return NULL;
00190 }
00191
00192 if (master)
00193 {
00194 for (i = 0; i < size + 16; i++)
00195 {
00196 ((char *) (r->mbuff_address))[i] = 0;
00197 }
00198 }
00199 r->local_pointer = rtlnml_malloc (size);
00200 r->rtlnml_allocated_local_pointer = 1;
00201 r->direct_data_pointer = (void *) (((char *) r->mbuff_address) + 16);
00202 r->header = (struct RTLNML_HEADER *) r->mbuff_address;
00203 r->max_message_size = size;
00204 return r;
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 int
00217 rtlnml_get_direct_pointer_for_read (rtlnml_t r, void **p)
00218 {
00219 if (r->last_id_read == r->header->first_message_count)
00220 {
00221 return RTLNML_READ_OLD;
00222 }
00223 if (r->header->first_message_count != r->header->second_message_count)
00224 {
00225 return RTLNML_SPLIT_READ_ERROR;
00226 }
00227 r->last_id_read = r->header->first_message_count;
00228 *p = r->direct_data_pointer;
00229 return r->header->message_type;
00230 }
00231
00232 int
00233 rtlnml_release_direct_pointer_for_read (rtlnml_t r, void **p)
00234 {
00235 *p = NULL;
00236 if (r->header->second_message_count != r->last_id_read)
00237 {
00238 return RTLNML_SPLIT_READ_ERROR;
00239 }
00240 return r->header->message_type;
00241 }
00242
00243 int
00244 rtlnml_get_direct_pointer_for_write (rtlnml_t r, void **p)
00245 {
00246 r->header->first_message_count++;
00247 *p = r->direct_data_pointer;
00248 return (0);
00249 }
00250
00251 int
00252 rtlnml_release_direct_pointer_for_write (rtlnml_t r, void **p, long msg_type,
00253 unsigned long msg_size)
00254 {
00255 *p = NULL;
00256 r->header->message_type = msg_type;
00257 r->header->message_size = msg_size;
00258 r->header->second_message_count = r->header->first_message_count;
00259 if (msg_size <= r->max_message_size && msg_size > 0)
00260 {
00261 return (-1);
00262 }
00263 return (0);
00264 }
00265
00266
00267
00268
00269
00270 long
00271 rtlnml_read (rtlnml_t r)
00272 {
00273 long orig_last_id_read = r->last_id_read;
00274 long msg_type;
00275 if (r->last_id_read == r->header->first_message_count)
00276 {
00277 return RTLNML_READ_OLD;
00278 }
00279 if (r->header->first_message_count != r->header->second_message_count)
00280 {
00281 return RTLNML_SPLIT_READ_ERROR;
00282 }
00283 if (r->header->message_size <= 0
00284 || r->header->message_size > r->max_message_size)
00285 {
00286 return RTLNML_READ_ERROR;
00287 }
00288 r->last_id_read = r->header->first_message_count;
00289 msg_type = r->header->message_type;
00290 #ifdef USE_BCOPY
00291 bcopy (r->direct_data_pointer, r->local_pointer, r->header->message_size);
00292 #else
00293 memcpy (r->local_pointer, r->direct_data_pointer, r->header->message_size);
00294 #endif
00295 if (r->last_id_read != r->header->second_message_count)
00296 {
00297 r->last_id_read = orig_last_id_read;
00298 return RTLNML_SPLIT_READ_ERROR;
00299 }
00300 return msg_type;
00301 }
00302
00303
00304
00305
00306 long
00307 rtlnml_write (rtlnml_t r, void *data,
00308 long msg_type,
00309 unsigned long msg_size)
00310 {
00311 if (msg_size <= 0 || msg_size > r->max_message_size)
00312 {
00313 return RTLNML_WRITE_ERROR;
00314 }
00315 r->header->first_message_count++;
00316 #ifdef USE_BCOPY
00317 bcopy (data, r->direct_data_pointer, msg_size);
00318 #else
00319 memcpy (r->direct_data_pointer, data, msg_size);
00320 #endif
00321 r->header->message_size = msg_size;
00322 r->header->message_type = msg_type;
00323 r->header->second_message_count = r->header->first_message_count;
00324 return (RTLNML_WRITE_OK);
00325 }
00326
00327
00328
00329 void *
00330 rtlnml_get_local_pointer (rtlnml_t r)
00331 {
00332 return r->local_pointer;
00333 }
00334
00335
00336 extern void
00337 rtlnml_set_local_pointer (rtlnml_t r, void *p)
00338 {
00339 if (NULL != r->local_pointer && r->rtlnml_allocated_local_pointer)
00340 {
00341 rtlnml_free (r->local_pointer);
00342 }
00343 r->rtlnml_allocated_local_pointer = 0;
00344 r->local_pointer = p;
00345 }
00346
00347
00348 void
00349 rtlnml_close (rtlnml_t r, const char *bufname)
00350 {
00351 if (NULL != r)
00352 {
00353 if (NULL != r->mbuff_address)
00354 {
00355 #ifdef rtai
00356 rtai_kfree (r->key);
00357 #else
00358 #ifdef linux_rtai
00359 rtai_free (r->key, r->mbuff_address);
00360 #else
00361 mbuff_free (bufname, r->mbuff_address);
00362 #endif
00363 #endif
00364 r->mbuff_address = NULL;
00365 }
00366 if (NULL != r->local_pointer && r->rtlnml_allocated_local_pointer)
00367 {
00368 rtlnml_free (r->local_pointer);
00369 r->local_pointer = NULL;
00370 }
00371 rtlnml_free (r);
00372 }
00373 }
00374
00375
00376
00377 void
00378 rtlnml_exit ()
00379 {
00380 }