xenomai与普通linux进程之间通信——XDDP(RT->nRT)
2016-08-09 19:33
686 查看
*
* XDDP-based RT/NRT threads communication demo.
*
* Real-time Xenomai threads and regular Linux threads may want to
* exchange data in a way that does not require the former to leave
* the real-time domain (i.e. secondary mode). Message pipes - as
* implemented by the RTDM-based XDDP protocol - are provided for this
* purpose.
*
* On the Linux domain side, pseudo-device files named /dev/rtp<minor>
* give regular POSIX threads access to non real-time communication
* endpoints, via the standard character-based I/O interface. On the
* Xenomai domain side, sockets may be bound to XDDP ports, which act
* as proxies to send and receive data to/from the associated
* pseudo-device files. Ports and pseudo-device minor numbers are
* paired, meaning that e.g. port 7 will proxy the traffic for
* /dev/rtp7. Therefore, port numbers may range from 0 to
* CONFIG_XENO_OPT_PIPE_NRDEV - 1.
*
* All data sent through a bound/connected XDDP socket via sendto(2) or
* write(2) will be passed to the peer endpoint in the Linux domain,
* and made available for reading via the standard read(2) system
* call. Conversely, all data sent using write(2) through the non
* real-time endpoint will be conveyed to the real-time socket
* endpoint, and made available to the recvfrom(2) or read(2) system
* calls.
xenomai的例程是两个线程之间通信。
我想写成两个程序之间的通信,xenomai将数据传输到XDDP_PORT
这里设置/dev/rtp0
实时进程将数据传到这里之后,普通进程就可以像访问其他文件一样,直接访问了。
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define XDDP_PORT 0
static void fail(const char *reason)
{
perror(reason);
exit(EXIT_FAILURE);
}
int main()
{
char buf[128],*devname;
memset(buf,0,sizeof(buf));
int fd, ret,outwrite;
if(asprintf(&devname,"dev/rtp%d",XDDP_PORT)<0)
fail("asprintf");
fd = open("/dev/rtp0", O_RDWR);
free(devname);
if(fd<0)
fail("open rtp0");
//out = open("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
//while(read(in,&c,1) == 1)
// write(out,&c,1);
for(;;){
ret=read(fd,buf,sizeof(buf));
if(ret <=0)
fail("read");
outwrite=write(1,buf,sizeof(buf));
//puts(buf);
}
exit(0);
}
今天七夕。所以把输出特意写成这样。
祝福
*
* XDDP-based RT/NRT threads communication demo.
*
* Real-time Xenomai threads and regular Linux threads may want to
* exchange data in a way that does not require the former to leave
* the real-time domain (i.e. secondary mode). Message pipes - as
* implemented by the RTDM-based XDDP protocol - are provided for this
* purpose.
*
* On the Linux domain side, pseudo-device files named /dev/rtp<minor>
* give regular POSIX threads access to non real-time communication
* endpoints, via the standard character-based I/O interface. On the
* Xenomai domain side, sockets may be bound to XDDP ports, which act
* as proxies to send and receive data to/from the associated
* pseudo-device files. Ports and pseudo-device minor numbers are
* paired, meaning that e.g. port 7 will proxy the traffic for
* /dev/rtp7. Therefore, port numbers may range from 0 to
* CONFIG_XENO_OPT_PIPE_NRDEV - 1.
*
* All data sent through a bound/connected XDDP socket via sendto(2) or
* write(2) will be passed to the peer endpoint in the Linux domain,
* and made available for reading via the standard read(2) system
* call. Conversely, all data sent using write(2) through the non
* real-time endpoint will be conveyed to the real-time socket
* endpoint, and made available to the recvfrom(2) or read(2) system
* calls.
xenomai的例程是两个线程之间通信。
我想写成两个程序之间的通信,xenomai将数据传输到XDDP_PORT
这里设置/dev/rtp0
实时进程将数据传到这里之后,普通进程就可以像访问其他文件一样,直接访问了。
一:xenomai端源代码
/* * XDDP-based RT/NRT threads communication demo. * * Real-time Xenomai threads and regular Linux threads may want to * exchange data in a way that does not require the former to leave * the real-time domain (i.e. secondary mode). Message pipes - as * implemented by the RTDM-based XDDP protocol - are provided for this * purpose. * * On the Linux domain side, pseudo-device files named /dev/rtp<minor> * give regular POSIX threads access to non real-time communication * endpoints, via the standard character-based I/O interface. On the * Xenomai domain side, sockets may be bound to XDDP ports, which act * as proxies to send and receive data to/from the associated * pseudo-device files. Ports and pseudo-device minor numbers are * paired, meaning that e.g. port 7 will proxy the traffic for * /dev/rtp7. Therefore, port numbers may range from 0 to * CONFIG_XENO_OPT_PIPE_NRDEV - 1. * * All data sent through a bound/connected XDDP socket via sendto(2) or * write(2) will be passed to the peer endpoint in the Linux domain, * and made available for reading via the standard read(2) system * call. Conversely, all data sent using write(2) through the non * real-time endpoint will be conveyed to the real-time socket * endpoint, and made available to the recvfrom(2) or read(2) system * calls. * * Both threads can use the bi-directional data path to send and * receive datagrams in a FIFO manner, as illustrated by the simple * echoing process implemented by this program. * * realtime_thread------------------------------>-------+ * => get socket | * => bind socket to port 0 v * => write traffic to NRT domain via sendto() | * => read traffic from NRT domain via recvfrom() <--|--+ * | | * regular_thread---------------------------------------+ | * => open /dev/rtp0 | ^ * => read traffic from RT domain via read() | | * => echo traffic back to RT domain via write() +--+ * * See Makefile in this directory for build directives. * * NOTE: XDDP is a replacement for the legacy RT_PIPE interface * available from the native skin until Xenomai 3. */ #include <sys/mman.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <string.h> #include <malloc.h> #include <pthread.h> #include <fcntl.h> #include <errno.h> #include <rtdk.h> #include <rtdm/rtipc.h> pthread_t rt, nrt; #define XDDP_PORT 0 /* [0..CONFIG-XENO_OPT_PIPE_NRDEV - 1] */ static const char *msg[] = { // "Surfing With The Alien", "HanQi love you, be with you \n", "Lords of Karma", "Banana Mango", "Psycho Monkey", "Luminous Flesh Giants", "Moroccan Sunset", "Satch Boogie", "Flying In A Blue Dream", "Ride", "Summer Song", "Speed Of Light", "Crystal Planet", "Raspberry Jam Delta-V", "Champagne?", "Clouds Race Across The Sky", "Engines Of Creation" }; static void fail(const char *reason) { perror(reason); exit(EXIT_FAILURE); } static void *realtime_thread(void *arg) { struct sockaddr_ipc saddr; int ret, s, n = 0, len; struct timespec ts; size_t poolsz; char buf[128]; /* * Get a datagram socket to bind to the RT endpoint. Each * endpoint is represented by a port number within the XDDP * protocol namespace. */ s = socket(AF_RTIPC, SOCK_DGRAM, IPCPROTO_XDDP); if (s < 0) { perror("socket"); exit(EXIT_FAILURE); } /* * Set a local 16k pool for the RT endpoint. Memory needed to * convey data 4000 grams will be pulled from this pool, instead of * Xenomai's system pool. */ poolsz = 16384; /* bytes */ ret = setsockopt(s, SOL_XDDP, XDDP_POOLSZ, &poolsz, sizeof(poolsz)); if (ret) fail("setsockopt"); /* * Bind the socket to the port, to setup a proxy to channel * traffic to/from the Linux domain. * * saddr.sipc_port specifies the port number to use. */ memset(&saddr, 0, sizeof(saddr)); saddr.sipc_family = AF_RTIPC; saddr.sipc_port = XDDP_PORT; ret = bind(s, (struct sockaddr *)&saddr, sizeof(saddr)); if (ret) fail("bind"); for (;;) { len = strlen(msg ); /* * Send a datagram to the NRT endpoint via the proxy. * We may pass a NULL destination address, since a * bound socket is assigned a default destination * address matching the binding address (unless * connect(2) was issued before bind(2), in which case * the former would prevail). */ ret = sendto(s, msg , len, 0, NULL, 0); if (ret != len) fail("sendto"); rt_printf("%s: sent %d bytes, \"%.*s\"\n", __FUNCTION__, ret, ret, msg ); /* Read back packets echoed by the regular thread */ /* ret = recvfrom(s, buf, sizeof(buf), 0, NULL, 0); if (ret <= 0) fail("recvfrom"); rt_printf(" => \"%.*s\" echoed by peer\n", ret, buf); n = (n + 1) % (sizeof(msg) / sizeof(msg[0])); /* * We run in full real-time mode (i.e. primary mode), * so we have to let the system breathe between two * iterations. */ ts.tv_sec = 0; ts.tv_nsec = 500000000; /* 500 ms */ clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL); } return NULL; } static void *regular_thread(void *arg) { char buf[128], *devname; int fd, ret; if (asprintf(&devname, "/dev/rtp%d", XDDP_PORT) < 0) fail("asprintf"); /* fd = open(devname, O_RDWR); free(devname); if (fd < 0) fail("open"); for (;;) { /* Get the next message from realtime_thread. */ /* ret = read(fd, buf, sizeof(buf)); if (ret <= 0) fail("read"); /* Echo the message back to realtime_thread. */ /* ret = write(fd, buf, ret); if (ret <= 0) fail("write"); } */ return NULL; } static void cleanup_upon_sig(int sig) { pthread_cancel(rt); pthread_cancel(nrt); signal(sig, SIG_DFL); pthread_join(rt, NULL); pthread_join(nrt, NULL); } int main(int argc, char **argv) { struct sched_param rtparam = { .sched_priority = 42 }; pthread_attr_t rtattr, regattr; sigset_t mask, oldmask; mlockall(MCL_CURRENT | MCL_FUTURE); sigemptyset(&mask); sigaddset(&mask, SIGINT); signal(SIGINT, cleanup_upon_sig); sigaddset(&mask, SIGTERM); signal(SIGTERM, cleanup_upon_sig); sigaddset(&mask, SIGHUP); signal(SIGHUP, cleanup_upon_sig); pthread_sigmask(SIG_BLOCK, &mask, &oldmask); /* * This is a real-time compatible printf() package from * Xenomai's RT Development Kit (RTDK), that does NOT cause * any transition to secondary (i.e. non real-time) mode when * writing output. */ rt_print_auto_init(1); pthread_attr_init(&rtattr); pthread_attr_setdetachstate(&rtattr, PTHREAD_CREATE_JOINABLE); pthread_attr_setinheritsched(&rtattr, PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedpolicy(&rtattr, SCHED_FIFO); pthread_attr_setschedparam(&rtattr, &rtparam); errno = pthread_create(&rt, &rtattr, &realtime_thread, NULL); if (errno) fail("pthread_create"); pthread_attr_init(®attr); pthread_attr_setdetachstate(®attr, PTHREAD_CREATE_JOINABLE); pthread_attr_setinheritsched(®attr, PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedpolicy(®attr, SCHED_OTHER); errno = pthread_create(&nrt, ®attr, ®ular_thread, NULL); if (errno) fail("pthread_create"); sigsuspend(&oldmask); return 0; }
二:普通linux程序
#include <unistd.h>#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define XDDP_PORT 0
static void fail(const char *reason)
{
perror(reason);
exit(EXIT_FAILURE);
}
int main()
{
char buf[128],*devname;
memset(buf,0,sizeof(buf));
int fd, ret,outwrite;
if(asprintf(&devname,"dev/rtp%d",XDDP_PORT)<0)
fail("asprintf");
fd = open("/dev/rtp0", O_RDWR);
free(devname);
if(fd<0)
fail("open rtp0");
//out = open("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
//while(read(in,&c,1) == 1)
// write(out,&c,1);
for(;;){
ret=read(fd,buf,sizeof(buf));
if(ret <=0)
fail("read");
outwrite=write(1,buf,sizeof(buf));
//puts(buf);
}
exit(0);
}
三:运行结果
今天七夕。所以把输出特意写成这样。
祝福
相关文章推荐
- linux 下mysql忘记密码解决方法
- centos7上安装aapt
- Linux文本处理工具grep
- 夺命雷公狗---linux之红帽的安装
- linux下c程序调用reboot函数实现直接重启
- 夺命雷公狗---linux之centos的安装
- centos之lnmp
- 学好linux决心书
- 终于完全学会fdisk 分配虚拟机命令了
- Centos6下创建Centos6基础镜像
- 四组王永盛学习Linux的决心
- Linux基础(一)
- Linux系统下源码安装rz/sz命令
- centos7之lamp环境搭建
- Python的Eclipse+PyDev编程环境搭建(Linux系统)
- linux文件与目录管理
- 虚拟机常见错误
- linux crontab 调试
- Linux基本命令一
- Linux基本命令一