RTLinux下的一种实时应用通信机制
[读/写操作]
intrtl_get(unsignedintfifo,char*buf,intcount);
从FIFO中读出长度为count字节的数据,存放buf之中。
Intrtf_put(unsignedintfifo,char*buf,intcount);
将长度为count字节的数据写入FIFO中。
Intrtf_create_handle(unsignedintfifo,int(&handler)(unsignedintfifo));
创建一个回调函数句柄,当FIFO被Linux进程读/写时,被调用。通常与rtl_get结合使用,用于异步的从Linux进程中接收数据,从而避免采用轮询的方式。
2.2共享内存
共享内存是指被闲置出来专用于内核空间和用户空间进行通信的内存区域。相对于FIFO具有如下特点:
*应用程序必须自己定义相应的协议,对于写入共享数据区域的有数据进行保护,如同步控制等。
*数据可以既定格式读/写,各个数据域的更新十分便易。
*不是点对点的通信通道,可以支持多生产者、多消费者的使用模式,能够同时被多个线程访问。
在RTLinux下,共享内存的使用可采用以下两种方式:
(1)利用RTLinux中附带的mbuff模块
在使用mbuff之前,要求系统中已经加载了mbuff.o模块。该模块中的两个函数被分别用于分配和释放所需的内存空间。
#include<mbuff.h>
[分配]
void*mbuff_alloc(constchar*name,intsize);
从内核空间中分配一块与name相连,大小为size字节的内存空间,返回地址指针,设备这块空间的引用标识为1。如与name相连的内存空间已经存在,就仅仅返回指向该空间的地址指针,同时将其引用标识加1。
[释放]
voidmbuff_free(constchar*name,intsize);
将mbuff的引用标识减1。当引用标识被减为0时,释放mbuff。
注意:①mbuff_alloc使用了vmalloc函数,由于分配内核空间的需要,会交换出一系列的内核空间页面,所以在实时线程、中断处理线程、定时器中断线程中调用这个函数是十分危险的。
②在进程结束前,一定要调用mbuff_free函数。Mbuff所占内存空间不会因为其引用进程的结束而自行释放。
(2)高地址空间物理内存的直接隔离
在系统启动时,隔离出一定大小的高地址空间物理内存,使其脱离系统运行环境,作为专用的共享内存区域。
图4共享内存互斥操作流程图
在Linux启动配置文件中,插入一行以append关键字起始的命令行,即可实现高端内存空间的隔离。修改后的/etc/lilo.conf文件如下所示:
image=/boot/zImage
label=rtlinuxX.X
root=/dev/hda2
read_only
append=“mem=Xm”
其中,mem的值对应于被隔离空间的起始地址,可以由物理内存总容量减去所需共享空间容量得到。但是必须注意,被隔离出的共享空间的容量必须小于
/usr/include/asm/param.h文件中定义的页面长度。IntelPentium系列芯片的页面长度为4MB。
对共享内存空间的存取操作通过访问其基址来实现。必须首先定义共享内存空间的基址。
#defineBASE_ADDRESS(127×0x100000)
在实时和非实时模块中有不同的基址访问方法。写时模块运行于内核地址空间,可以直接将基址作为地址指针进行存取,使用语句如下:
unsignedshort*sharemem;
sharemem=(unsignedshort*)__va(BASE_ADDRESS);
非实时模块运行于用户地址空间,必须先将该物理地址映射入该进程虚拟地址空间后,才能对其进行存取。使用命令如下:
#include<unis 《RTLinux下的一种实时应用通信机制(第2页)》