base/include/rtai_shm.h

Go to the documentation of this file.
00001 /** 00002 * @ingroup shm 00003 * @file 00004 * 00005 * Interface of the @ref shm "RTAI SHM module". 00006 * 00007 * @author Paolo Mantegazza 00008 * 00009 * @note Copyright &copy; 1999-2004 Paolo Mantegazza <mantegazza@aero.polimi.it> 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License as 00013 * published by the Free Software Foundation; either version 2 of the 00014 * License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software 00023 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00024 */ 00025 00026 /* 00027 ACKNOWLEDGMENTS: 00028 - The suggestion and the code for mmapping at a user specified address is due to Trevor Woolven (trevw@zentropix.com). 00029 */ 00030 00031 00032 #ifndef _RTAI_SHM_H 00033 #define _RTAI_SHM_H 00034 00035 /** @addtogroup shm 00036 *@{*/ 00037 00038 #define GLOBAL_HEAP_ID 0x9ac6d9e5 // nam2num("RTGLBH"); 00039 00040 #define USE_VMALLOC 0 00041 #define USE_GFP_KERNEL 1 00042 #define USE_GFP_ATOMIC 2 00043 #define USE_GFP_DMA 3 00044 00045 /** 00046 * Allocate a chunk of memory to be shared inter-intra kernel modules and 00047 * Linux processes. 00048 * 00049 * @internal 00050 * 00051 * rtai_kalloc is used to allocate shared memory from kernel space. 00052 * 00053 * @param name is an unsigned long identifier; 00054 * 00055 * @param size is the amount of required shared memory; 00056 * 00057 * rtai_kmalloc is a legacy helper macro, the real job is carried out by a 00058 * call to rt_shm_alloc() with the same name, size and with vmalloc support. 00059 * This function should not be used in newly developed applications. See 00060 * rt_shm_alloc for more details. 00061 * 00062 * @returns a valid address on succes, 0 on failure. 00063 * 00064 */ 00065 00066 #define rtai_kmalloc(name, size) \ 00067 rt_shm_alloc(name, size, USE_VMALLOC) // legacy 00068 00069 /** 00070 * Free a chunk of shared memory being shared inter-intra kernel modules and 00071 * Linux processes. 00072 * 00073 * rtai_kfree is used to free a shared memory chunk from kernel space. 00074 * 00075 * @param name is the unsigned long identifier used when the memory was 00076 * allocated; 00077 * 00078 * rtai_kfree is a legacy helper macro, the real job is carried out by a 00079 * call to rt_shm_free with the same name. This function should not be used 00080 * in newly developed applications. See rt_shm_free for more details. 00081 * 00082 * @returns the size of the succesfully freed memory, 0 on failure. 00083 * 00084 */ 00085 00086 #define rtai_kfree(name) \ 00087 rt_shm_free(name) // legacy 00088 00089 #if defined(__KERNEL__) 00090 00091 #include <linux/module.h> 00092 #include <linux/version.h> 00093 #include <linux/vmalloc.h> 00094 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 00095 #include <linux/wrapper.h> 00096 #else /* >= 2.6.0 */ 00097 #include <linux/mm.h> 00098 #define mem_map_reserve(p) SetPageReserved(p) 00099 #define mem_map_unreserve(p) ClearPageReserved(p) 00100 #endif /* < 2.6.0 */ 00101 00102 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10) 00103 static inline int remap_page_range(struct vm_area_struct *vma, unsigned long uvaddr, unsigned long paddr, unsigned long size, pgprot_t prot) 00104 { 00105 return remap_pfn_range(vma, uvaddr, paddr >> PAGE_SHIFT, size, prot); 00106 } 00107 #endif 00108 00109 #include <rtai_malloc.h> 00110 00111 #include <asm/rtai_shm.h> 00112 00113 #ifdef __cplusplus 00114 extern "C" { 00115 #endif /* __cplusplus */ 00116 00117 int __rtai_shm_init(void); 00118 00119 void __rtai_shm_exit(void); 00120 00121 void *rt_shm_alloc(unsigned long name, 00122 int size, 00123 int suprt); 00124 00125 #define rt_shm_alloc_adr(adr, name, size) \ 00126 rt_shm_alloc(name, size, suprt) 00127 00128 int rt_shm_free(unsigned long name); 00129 00130 void *rt_heap_open(unsigned long name, 00131 int size, 00132 int suprt); 00133 00134 #define rt_heap_open_adr(adr, name, size, suprt) \ 00135 rt_heap_open(name, size, suprt) 00136 00137 void *rt_halloc(int size); 00138 00139 void rt_hfree(void *addr); 00140 00141 void *rt_named_halloc(unsigned long name, 00142 int size); 00143 00144 void rt_named_hfree(void *addr); 00145 00146 void *rt_named_malloc(unsigned long name, 00147 int size); 00148 00149 void rt_named_free(void *addr); 00150 00151 void *rvmalloc(unsigned long size); 00152 00153 void rvfree(void *mem, 00154 unsigned long size); 00155 00156 int rvmmap(void *mem, 00157 unsigned long memsize, 00158 struct vm_area_struct *vma); 00159 00160 void *rkmalloc(int *size, 00161 int suprt); 00162 00163 void rkfree(void *mem, 00164 unsigned long size); 00165 00166 int rkmmap(void *mem, 00167 unsigned long memsize, 00168 struct vm_area_struct *vma); 00169 00170 #ifdef __cplusplus 00171 } 00172 #endif /* __cplusplus */ 00173 00174 #else /* !__KERNEL__ */ 00175 00176 #include <fcntl.h> 00177 #include <unistd.h> 00178 #include <sys/mman.h> 00179 #include <sys/ioctl.h> 00180 #include <rtai_lxrt.h> 00181 00182 //#define SHM_USE_LXRT 00183 00184 #define RTAI_SHM_DEV "/dev/rtai_shm" 00185 00186 static inline void *_rt_shm_alloc(void *start, unsigned long name, int size, int suprt, int isheap) 00187 { 00188 int hook; 00189 void *adr; 00190 if ((hook = open(RTAI_SHM_DEV, O_RDWR)) <= 0) { 00191 return 0; 00192 } else { 00193 struct { unsigned long name, arg, suprt; } arg = { name, size, suprt }; 00194 #ifdef SHM_USE_LXRT 00195 if ((size = rtai_lxrt(BIDX, SIZARG, SHM_ALLOC, &arg).i[LOW])) { 00196 #else 00197 if ((size = ioctl(hook, SHM_ALLOC, (unsigned long)(&arg)))) { 00198 #endif 00199 if ((adr = mmap(start, size, PROT_WRITE | PROT_READ, MAP_SHARED | MAP_LOCKED, hook, 0)) == (void *)-1) {; 00200 #ifdef SHM_USE_LXRT 00201 rtai_lxrt(BIDX, sizeof(name), SHM_FREE, &name); 00202 #else 00203 ioctl(hook, SHM_FREE, &name); 00204 #endif 00205 adr = 0; 00206 } 00207 if (isheap) { 00208 arg.arg = (unsigned long)adr; 00209 #ifdef SHM_USE_LXRT 00210 rtai_lxrt(BIDX, SIZARG, HEAP_SET, &arg); 00211 #else 00212 ioctl(hook, HEAP_SET, &arg); 00213 #endif 00214 } 00215 } else { 00216 adr = 0; 00217 } 00218 } 00219 close(hook); 00220 return adr; 00221 } 00222 00223 #define rt_shm_alloc(name, size, suprt) \ 00224 _rt_shm_alloc(0, name, size, suprt, 0) 00225 00226 #define rt_heap_open(name, size, suprt) \ 00227 _rt_shm_alloc(0, name, size, suprt, 1) 00228 00229 /** 00230 * Allocate a chunk of memory to be shared inter-intra kernel modules and 00231 * Linux processes. 00232 * 00233 * @internal 00234 * 00235 * rtai_malloc is used to allocate shared memory from user space. 00236 * 00237 * @param name is an unsigned long identifier; 00238 * 00239 * @param size is the amount of required shared memory; 00240 * 00241 * rtai_malloc is a legacy helper macro, the real job is carried out by a 00242 * call to rt_shm_alloc() with the same name, size and with vmalloc support. 00243 * This function should not be used in newly developed applications. See 00244 * rt_shm_alloc fro more details. 00245 * 00246 * @returns a valid address on succes, 0 on failure. 00247 * 00248 */ 00249 00250 #define rtai_malloc(name, size) \ 00251 _rt_shm_alloc(0, name, size, USE_VMALLOC, 0) // legacy 00252 00253 /** 00254 * Allocate a chunk of memory to be shared inter-intra kernel modules and Linux 00255 * processes. 00256 * 00257 * rt_shm_alloc_adr is used to allocate in user space. 00258 * 00259 * @param start_address is a user desired address where the allocated memory 00260 * should be mapped in user space; 00261 * 00262 * @param name is an unsigned long identifier; 00263 * 00264 * @param size is the amount of required shared memory. 00265 * 00266 * @param suprt is the kernel allocation method to be used, it can be: 00267 * - USE_VMALLOC, use vmalloc; 00268 * - USE_GFP_KERNEL, use kmalloc with GFP_KERNEL; 00269 * - USE_GFP_ATOMIC, use kmalloc with GFP_ATOMIC; 00270 * - USE_GFP_DMA, use kmalloc with GFP_DMA. 00271 * 00272 * Since @c name can be a clumsy identifier, services are provided to 00273 * convert 6 characters identifiers to unsigned long, and vice versa. 00274 * 00275 * @see the functions nam2num() and num2nam(). 00276 * 00277 * It must be remarked that only the very first call does a real allocation, 00278 * any subsequent call to allocate with the same name from anywhere will just 00279 * increase the usage count and map the area to user space, or return the 00280 * related pointer to the already allocated space in kernel space. The function 00281 * returns a pointer to the allocated memory, appropriately mapped to the memory 00282 * space in use. So if one is really sure that the named shared memory has been 00283 * allocated already parameters size and suprt are not used and can be 00284 * assigned any value. 00285 * 00286 * @note If the same process calls rtai_malloc_adr and rtai_malloc() twice in 00287 * the same process it get a zero return value on the second call. 00288 * 00289 * @returns a valid address on succes, 0 on failure. 00290 * 00291 */ 00292 00293 #define rt_shm_alloc_adr(start_address, name, size, suprt) \ 00294 _rt_shm_alloc(start_address, name, size, suprt, 0) 00295 00296 #define rt_heap_open_adr(start, name, size, suprt) \ 00297 _rt_shm_alloc(start, name, size, suprt, 1) 00298 00299 /** 00300 * Allocate a chunk of memory to be shared inter-intra kernel modules and 00301 * Linux processes. 00302 * 00303 * @internal 00304 * 00305 * rtai_malloc_adr is used to allocate shared memory from user space. 00306 * 00307 * @param start_address is the adr were the shared memory should be mapped. 00308 * 00309 * @param name is an unsigned long identifier; 00310 * 00311 * @param size is the amount of required shared memory; 00312 * 00313 * rtai_malloc_adr is a legacy helper macro, the real job is carried out by a 00314 * call to rt_shm_alloc_adr() with the same name, size and with vmalloc support. 00315 * This function should not be used in newly developed applications. See 00316 * rt_shm_alloc_adr for more details. 00317 * 00318 * @returns a valid address on succes, 0 on failure. 00319 * 00320 */ 00321 00322 #define rtai_malloc_adr(start_address, name, size) \ 00323 _rt_shm_alloc(start_address, name, size, USE_VMALLOC, 0) // legacy 00324 00325 static inline int rt_shm_free(unsigned long name) 00326 { 00327 int hook, size; 00328 struct { void *nameadr; } arg = { &name }; 00329 if ((hook = open(RTAI_SHM_DEV, O_RDWR)) <= 0) { 00330 return 0; 00331 } 00332 // no SHM_FREE needed, we release it all and munmap will do it through 00333 // the vma close operation provided by shm.c 00334 #ifdef SHM_USE_LXRT 00335 if ((size = rtai_lxrt(BIDX, SIZARG, SHM_SIZE, &arg).i[LOW])) { 00336 #else 00337 if ((size = ioctl(hook, SHM_SIZE, (unsigned long)&arg))) { 00338 #endif 00339 if (munmap((void *)name, size)) { 00340 size = 0; 00341 } 00342 } 00343 close(hook); 00344 return size; 00345 } 00346 00347 /** 00348 * Free a chunk of shared memory being shared inter-intra 00349 * kernel modules and Linux processes. 00350 * 00351 * rtai_free is used to free a shared memory chunk from user space. 00352 * 00353 * @param name is the unsigned long identifier used when the memory was 00354 * allocated; 00355 * 00356 * @param adr is not used. 00357 * 00358 * rtai_free is a legacy helper macro, the real job is carried out by a 00359 * call to rt_shm_free with the same name. This function should not be used 00360 * in newly developed applications. See rt_shm_alloc_adr for more details. 00361 * 00362 * @returns the size of the succesfully freed memory, 0 on failure. 00363 * 00364 */ 00365 00366 #define rtai_free(name, adr) \ 00367 rt_shm_free(name) // legacy 00368 00369 RTAI_PROTO(void *, rt_halloc, (int size)) 00370 { 00371 struct { long size; } arg = { size }; 00372 return rtai_lxrt(BIDX, SIZARG, HEAP_ALLOC, &arg).v[LOW]; 00373 } 00374 00375 RTAI_PROTO(void, rt_hfree, (void *addr)) 00376 { 00377 struct { void *addr; } arg = { addr }; 00378 rtai_lxrt(BIDX, SIZARG, HEAP_FREE, &arg); 00379 } 00380 00381 RTAI_PROTO(void *, rt_named_halloc, (unsigned long name, int size)) 00382 { 00383 struct { unsigned long name; long size; } arg = { name, size }; 00384 return rtai_lxrt(BIDX, SIZARG, HEAP_NAMED_ALLOC, &arg).v[LOW]; 00385 } 00386 00387 RTAI_PROTO(void, rt_named_hfree, (void *addr)) 00388 { 00389 struct { void *addr; } arg = { addr }; 00390 rtai_lxrt(BIDX, SIZARG, HEAP_NAMED_FREE, &arg); 00391 } 00392 00393 RTAI_PROTO(void *, rt_malloc, (int size)) 00394 { 00395 struct { long size; } arg = { size }; 00396 return rtai_lxrt(BIDX, SIZARG, MALLOC, &arg).v[LOW]; 00397 } 00398 00399 RTAI_PROTO(void, rt_free, (void *addr)) 00400 { 00401 struct { void *addr; } arg = { addr }; 00402 rtai_lxrt(BIDX, SIZARG, FREE, &arg); 00403 } 00404 00405 RTAI_PROTO(void *, rt_named_malloc, (unsigned long name, int size)) 00406 { 00407 struct { unsigned long name; long size; } arg = { name, size }; 00408 return rtai_lxrt(BIDX, SIZARG, NAMED_MALLOC, &arg).v[LOW]; 00409 } 00410 00411 RTAI_PROTO(void, rt_named_free, (void *addr)) 00412 { 00413 struct { void *addr; } arg = { addr }; 00414 rtai_lxrt(BIDX, SIZARG, NAMED_FREE, &arg); 00415 } 00416 00417 #endif /* __KERNEL__ */ 00418 00419 /** 00420 * Close a real time group heap being shared inter-intra kernel modules and 00421 * Linux processes. 00422 * 00423 * @internal 00424 * 00425 * rt_heap_close is used to close a previously opened real time group heap. 00426 * 00427 * @param name is the unsigned long identifier used to identify the heap. 00428 * 00429 * @param adr is not used. 00430 * 00431 * Analogously to what done by any allocation function this group real time 00432 * heap closing call have just the effect of decrementing a usage count, 00433 * unmapping any user space heap being closed, till the last is done, as that 00434 * is the one the really closes the group heap, freeing any allocated memory. 00435 * 00436 * @returns the size of the succesfully freed heap, 0 on failure. 00437 * 00438 */ 00439 00440 #define rt_heap_close(name, adr) rt_shm_free(name) 00441 00442 // aliases in use already, different heads different choices 00443 #define rt_heap_init rt_heap_open 00444 #define rt_heap_create rt_heap_open 00445 #define rt_heap_acquire rt_heap_open 00446 #define rt_heap_init_adr rt_heap_open_adr 00447 #define rt_heap_create_adr rt_heap_open_adr 00448 #define rt_heap_acquire_adr rt_heap_open_adr 00449 00450 #define rt_heap_delete rt_heap_close 00451 #define rt_heap_destroy rt_heap_close 00452 #define rt_heap_release rt_heap_close 00453 00454 // these have no aliases, and never will 00455 00456 /** 00457 * Open the global real time heap to be shared inter-intra kernel modules and 00458 * Linux processes. 00459 * 00460 * @internal 00461 * 00462 * rt_global_heap_open is used to open the global real time heap. 00463 * 00464 * The global heap is created by the shared memory module and its opening is 00465 * needed in user space to map it to the process address space. In kernel 00466 * space opening the global heap in a task is not required but should be done 00467 * anyhow, both for symmetry and to register its usage. 00468 * 00469 */ 00470 00471 #define rt_global_heap_open() rt_heap_open(GLOBAL_HEAP_ID, 0, 0) 00472 00473 /** 00474 * Close the global real time heap being shared inter-intra kernel modules and 00475 * Linux processes. 00476 * 00477 * @internal 00478 * 00479 * rt_global_heap_close is used to close the global real time heap. 00480 * 00481 * Closing a global heap in user space has just the effect of deregistering 00482 * its use and unmapping the related memory from a process address space. 00483 * In kernel tasks just the deregistration is performed. 00484 * The global real time heap is destroyed just a the rmmoding of the shared 00485 * memory module. 00486 * 00487 */ 00488 00489 #define rt_global_heap_close() rt_heap_close(GLOBAL_HEAP_ID, 0) 00490 00491 /*@}*/ 00492 00493 #endif /* !_RTAI_SHM_H */

Generated on Thu Nov 20 11:49:49 2008 for RTAI API by doxygen 1.3.8