RTAI用户空间编程(七)——共享内存通讯

10 篇文章 8 订阅

一. 创建函数

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 <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>  /* ENOMEM */
#include <stddef.h>       /* 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 <stdio.h>        /* printf() */
#include <stddef.h>       /* sizeof() */
#include <signal.h>       /* signal(), SIGINT */
#include <sys/mman.h>     /* PROT_READ, needed for rtai_shm.h */
#include <sys/types.h>        /* off_t, needed for rtai_shm.h */
#include <sys/fcntl.h>        /* O_RDWR, needed for rtai_shm.h */
#include <rtai_shm.h>     /* 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

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值