Qnx IPC通信PPS
Qnx自帶PPS服務,PPS全稱Persistent Publish/Subscribe Service,就是常見的P/S通信模式。
Qnx PPS的通信模式是異步的,Publisher和Subscriber也無需關心對方是否存在。
利用Qnx提供的PPS服務,Publisher可以通知多個Subscriber進行某種動作。
該圖是QNX官網的PPS示例場景。
- Applications和組件(比如Media、Radio、Phone等等)通過PPS交互消息。
官網鏈接:
http://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.pps.developer/topic/about.html
使用QNX PPS
Qnx 的PPS,是利用文件的方式實現的。所以使用起來,跟文件的讀寫差不多。
- Publisher端打開文件,寫入文件。
int fd = open( "/pps/example/button", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO );ssize_t len, bytes_written;
len = snprintf(buf, 256, "state::%s\npub1::%d", state ? "on" : "off", count);
bytes_written = write( fd, buf, len );
- Subscriber打開文件,監聽文件描述符產生的寫入事件,監聽可以使用epoll、select、ionotify(qnx提供)等等。
- 打開文件時“?”后面表示打開模式。delta表示增量模式,所謂增量模式,每次只讀取PPS數據中變更的部分。
int fd = open( "/pps/example/button?delta", O_RDONLY );
struct pollfd readfds[1];while (1) {readfds[0].fd = fd;readfds[0].events = POLLIN;int result = poll(readfds, 1, timeout);if(result != -1 && result != 0) {if( readfds[0].revents & POLLRDNORM ){// 也可以選擇其他讀取方式// 利用fd的讀文件方式有很多種num_bytes = read( fd, buf, sizeof(buf) );if (num_bytes > 0) {// 解析數據}}} }
- Publisher打開(不存在的時候創建)PPS服務路徑下(默認為/pps,可配置)的文件,往文件里寫入數據。Subscriber打開要監聽的文件(與Publisher一個文件),監聽該文件的寫入事件,當寫入時讀取該文件,即可。
完整的例子(QNX官網提供)
- Publisher
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>int main(int argc, char *argv[])
{int fd;int state = 0;char buf[256];struct stat stat_buf;int count = 0;ssize_t len, bytes_written;/* Is PPS running? */if (stat( "/pps", &stat_buf) != 0){if (errno == ENOENT)printf ("The PPS server isn't running.\n");elseperror ("stat (/pps)");return EXIT_FAILURE;}/* Create the "button" object (if it doesn't already exist). */fd = open( "/pps/example/button", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO );if ( fd < 0 ){perror ("Couldn't open /pps/example/button");return EXIT_FAILURE;}/* Loop forever, toggling the state of the button. */while ( 1 ){usleep (500);count++;len = snprintf(buf, 256, "state::%s\npub1::%d", state ? "on" : "off", count);bytes_written = write( fd, buf, len );if (bytes_written == -1){perror ("write()");}else if (bytes_written != len){printf ("Bytes written: %d String length: %d\n", bytes_written, len);}if ( state == 0 )state = 1;elsestate = 0;}return EXIT_SUCCESS;
}
- Subscriber
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/poll.h>int main(int argc, char *argv[])
{int fd;char buf[256];ssize_t num_bytes;int ret;struct pollfd readfds[1];int timeout = 2000;fd = open( "/pps/example/button?delta", O_RDONLY );if ( fd < 0 ){perror ("Couldn't open /pps/example/button");return EXIT_FAILURE;}/* Loop, echoing the attributes of the button. */while (1){readfds[0].fd = fd;readfds[0].events = POLLIN;switch ( ret = poll(readfds, 1, timeout ) ){case -1:/* An error occurred. */break;case 0:/* poll() timed out. */break;default:if( readfds[0].revents & POLLRDNORM ){num_bytes = read( fd, buf, sizeof(buf) );if (num_bytes > 0){write (STDOUT_FILENO, buf, (size_t) num_bytes);}}}}return EXIT_SUCCESS;
}