您的位置:首页 > 大数据 > 人工智能

Xenomai 实时线程 select 测试

2016-12-14 16:46 337 查看
Xenomai是linux内核的一个实时开发框架,可生成实时线程,基本能达到硬实时要求。

生成实时线程代码如下

 

       pthread_attr_tsvattr;

pthread_t svtid;

 

       pthread_attr_init(&svattr);

       pthread_attr_setdetachstate(&svattr,PTHREAD_CREATE_JOINABLE);

       pthread_attr_setinheritsched(&svattr,PTHREAD_EXPLICIT_SCHED);

       pthread_attr_setschedpolicy(&svattr,SCHED_FIFO);

       pthread_attr_setschedparam(&svattr,&svparam);

 

       errno= pthread_create(&svtid, &svattr, &server, NULL);

       if(errno)

              fail("pthread_create");

 

Xenomai 进程间通信方式分成Xenomai域内的IPC以及Xenomai域和Linux域之间的IPC,采用RTIPC的方式,给用户空间提供socket接口,实时应用通过调用对应的接口可以避免切换到Linux域而导致实时性降低。

 

进程间通信用socket接口时,在linux下可采用select进行多路复用,参考代码如下:

 

              FD_ZERO(&rset);

              FD_SET(sockfd1,&rset);

              FD_SET(sockfd2,&rset);

              maxfdp1= max(sockfd1, sockfd2) + 1;

              Select(maxfdp1,&rset, NULL, NULL, NULL);

 

              if(FD_ISSET(sockfd1, &rset)) {     /*socket1 is readable */

                     /*do something */

              }

 

              if(FD_ISSET(sockfd2, &rset)) {  /* socket2is readable */

                     /*do something */

              }

 

在实时域同样的代码则工作不正常,测试代码如下

 

       structsockaddr_ipc saddr, claddr;

       socklen_taddrlen;

       charbuf[128];

       size_tpoolsz;

       intret, s;

       fd_setrset;

 

       s= socket(AF_RTIPC, SOCK_DGRAM, IPCPROTO_IDDP);

       if(s < 0)

              fail("socket");

 

       /*

        * Set a local 32k pool for the serverendpoint. Memory needed

        * to convey datagrams will be pulled from thispool, instead

        * of Xenomai's system pool.

        */

       poolsz= 32768; /* bytes */

       ret= setsockopt(s, SOL_IDDP, IDDP_POOLSZ,

                      &poolsz, sizeof(poolsz));

       if(ret)

              fail("setsockopt");

 

       saddr.sipc_family= AF_RTIPC;

       saddr.sipc_port= IDDP_SVPORT;

       ret= bind(s, (struct sockaddr *)&saddr, sizeof(saddr));

       if(ret)

              fail("bind");

 

       for(;;) {

              FD_ZERO(&rset);

              FD_SET(s,&rset);

             

              ret= select(s + 1, &rset, NULL, NULL, NULL);

              if(ret < 0) {

                     fail("select");

              }

              /*can not reach here */

              addrlen= sizeof(saddr);

              ret= recvfrom(s, buf, sizeof(buf), 0,

                            (struct sockaddr *)&claddr,&addrlen);

              if(ret < 0) {

                     close(s);

                     fail("recvfrom");

              }

              rt_printf("%s:received %d bytes, \"%.*s\" from port %d\n",

                       __FUNCTION__, ret, ret, buf,claddr.sipc_port);

       }

 

并且如果配置实时域socket为非阻塞模式,则返回失败

void setnonblocking(int sock)

{

       intopts;

       opts=fcntl(sock,F_GETFL);

       if(opts<0)

       {

              perror("fcntl(sock,GETFL)");  /* 返回错误 */

              exit(1);

       }

       opts= opts|O_NONBLOCK;

       if(fcntl(sock,F_SETFL,opts)<0)

       {

              perror("fcntl(sock,SETFL,opts)");

              exit(1);

       }

}

 

测试结果:实时域socket使用select无法正常返回,Linux域暂时没发现这个问题
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Xenomai RT Linux