xenomai与普通linux进程之间通信——XDDP(nRT->RT)

    xiaoxiao2025-09-15  361

    上次测试了,从xenomai实时层到linux普通进程之间的通信。

    有朋友评论,并指出反向如何?非实时到实时进程之间的通信

    并提出了非常好的一个问题,非实时进程向实时进程传说数据的时候,实时进程如何知道有数据发来,并实时响应?

    第一阶段,我先研究了下,没有实时响应的情况。

    第一: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 *devname; char *buf[3]= { "buf1", "buf2", "buf3" }; char buf2[]="write to the xddp"; int n=0; 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(n;n<3;n++){ //ret=read(fd,buf,sizeof(buf)); ret=write(fd,buf2,sizeof(buf2)); {if(ret <=0) fail("write");} //n = (n + 1) % (sizeof(buf) / sizeof(buf[0])); //outwrite=write(1,buf[n],sizeof(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. * * 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 void fail(const char *reason) { perror(reason); exit(EXIT_FAILURE); } int main(int argc, char **argv) { /* * 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. */ 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 datagrams 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[n]); /* * 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[n], len, 0, NULL, 0); if (ret != len) fail("sendto"); rt_printf("%s: sent %d bytes, \"%.*s\"\n", __FUNCTION__, ret, ret, msg[n]); */ /* 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])); //} return 0; }

    三:测试

    四:总结

    在此期间,出过一个问题。   char buf2[]="write to the xddp"; 我定义为指针来char *buf2[],

    在写的时候sizeof[buf2]

    这样无论我的数据多长,接收到的只有前4个字符。

    很简单的原因,概念不清楚。指针占用4个字节。所以才出现这样的问题。

    另一个问题,当linux普通进程发送来数据时候,xenomai怎么知道有数据来了?有没有中断或者信号?

    下面研究这个问题。

    
    转载请注明原文地址: https://ju.6miu.com/read-1302675.html
    最新回复(0)