一. 创建函数
void *rtai_malloc_adr (void *adr, unsigned long name, int size);
void *rtai_malloc (unsigned long name, int size);
void *rtai_kmalloc (unsigned long name, int size);
//rtai_malloc_adr和rtai_malloc用于在用户空间分配而rtai_kmalloc用于在内核空间分配。
参数
adr 用户期望的地址,被分配的内存应该映射到用户空间。
name 无符号长标识符
size 需要的共享内存数量
由于name可以是一个复杂的标识符,系统提供了将6字符标识符转换为无符长整型的服务,反之亦然。由函数nam2num 和 num2nam实现。
unsigned long nam2num (const char *name);
void num2nam(unsigned long id, const char* name);
必须说,第一个分配做一个真正的分配, 从Linux进程调用的任何具有相同名称的后续分配,只是将区域映射到用户空间,或者返回相关指针到已经在内核空间中分配的空间。
这个函数返回一个指针指向被分配的内存,适当地映射到使用的内存空间。
函数返回
成功,返回一个有效地址
失败,返回0.
注意:如果同一个进程在同一个进程中调用了rtai_malloc_adr 和 rtai_malloc两次,将会在第二次调用时返回0.
二. Free函数
void rtai_free (unsigned long name, void *adr);
void rtai_kfree(void *adr);
rtai_free用于释放用户空间中一个以前分配的共享内存,rtai_kfree是用来在内核空间中做同样的操作。
参数
Name 当内存被分配时候使用的无符号长整型标识符
Adr 对应的地址
注意
类似分配函数的操作,释放调用只对取消映射共享内存有影响,这些共享内存到最后被释放,这时才是真正的释放分配的内存。
4. 示例代码(http://chrtai.sourceforge.net/)
/*
shm_task.c
Set up a periodic task that increments a heartbeat array in shared memory.
*/
#define MODULE
#define __KERNEL__
#include
#include
#include /* ENOMEM */
#include /* sizeof() */
#include "rtai.h"
#include "rtai_sched.h"
#include "rtai_shm.h"
#include "common.h" /* SHM_KEY, SHM_HOWMANY */
MODULE_LICENSE("GPL");
RT_TASK shm_task;
static RTIME shm_period_ns = 100000;
static int * shm_array = 0;
static void shm_function(int arg)
{
int heartbeat = 0;
int t;
while (1) {
heartbeat++;
/* make sure the memory has been allocated before we write to it */
if (0 != shm_array) {
/* now write to it */
for (t = 0; t < SHM_HOWMANY; t++) {
shm_array[t] = heartbeat;
}
}
rt_task_wait_period();
}
return;
}
int init_module(void)
{
int retval;
RTIME shm_period_count;
shm_array = rtai_kmalloc(SHM_KEY, SHM_HOWMANY * sizeof(int));
if (0 == shm_array) {
return -ENOMEM;
}
rt_set_periodic_mode();
shm_period_count = nano2count(shm_period_ns);
start_rt_timer(shm_period_count);
retval = rt_task_init(&shm_task, shm_function, 0, 1024,
RT_LOWEST_PRIORITY, 0, 0);
if (0 != retval) {
return retval;
}
retval = rt_task_make_periodic(&shm_task,
rt_get_time() + shm_period_count,
shm_period_count);
if (0 != retval) {
return retval;
}
return 0;
}
void cleanup_module(void)
{
rt_task_delete(&shm_task);
rtai_kfree(SHM_KEY);
return;
}
/*--------------------------------------------*/
#include /* printf() */
#include /* sizeof() */
#include /* signal(), SIGINT */
#include /* PROT_READ, needed for rtai_shm.h */
#include /* off_t, needed for rtai_shm.h */
#include /* O_RDWR, needed for rtai_shm.h */
#include /* rtai_malloc,free() */
#include "common.h" /* SHM_KEY, SHM_HOWMANY */
/*
This signal handler just sets the 'done' flag, which we will loop
on when printing the shared memory. This lets us quit nicely.
*/
static int done = 0;
static void quit(int sig)
{
done = 1;
}
int main(void)
{
int * shm_array;
int head, tail;
shm_array = rtai_malloc(SHM_KEY, SHM_HOWMANY * sizeof(int));
if (0 == shm_array) {
fprintf(stderr, "can't allocate shared memory\n");
return 1;
}
/*
Attach our signal hander to SIGINT, the signal raised when we hit
Control-C.
*/
signal(SIGINT, quit);
while (! done) {
/*
Read the first and last element of the array. The should be
the same, but if we are interrupted by the RT code in between
these reads, the tail will be newer.
*/
head = shm_array[0];
/* we could get interrupted here */
tail = shm_array[SHM_HOWMANY - 1];
/*
Print out head and tail of shared memory, and an error if
they're different.
*/
printf("%10d\t%10d\r", head, tail);
if (head != tail) {
printf("\nsplit read\n");
}
}
/*
Control-C stopped us, so let's exit nicely by freeing up our connection
to shared memory.
*/
rtai_free(SHM_KEY, shm_array);
return 0;
}
共享内存可以在应用程序之间使用,如一个实时任务程序,一个linux程序。Malloc成功的前提是加载了 rtai_shm.ko