首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C中的Linux串口

问C中的Linux串口
EN

Stack Overflow用户
提问于 2013-08-27 05:39:52
回答 2查看 1.5K关注 0票数 0

我用c++编写了一个读写串行port.But的程序,问题是我使用的是over循环,它不断地通过串口发送命令。

  1. 我想在串口上写一些命令
  2. 等待答案
  3. 编写另一个命令
  4. 等待一些答案,等等

我的密码是这样的:-

代码语言:javascript
复制
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>
#include <errno.h>
#include <time.h>

 int main()

  {   
   printf("\n");
   printf("Please wait till serial Port is  being Initialized .... \n");
   sleep(2);
   printf("\n................. Initializing ................\n");
   sleep(2);
   printf("\n");
   printf("\n\n");
   static int fd = 0;
       int len;
       char res[100];
       char s[100] = " Hellow World";


     struct termios options;

    //==================================================================
    //                  hard coaded port ttyO3
    //==================================================================

      fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); 
          fcntl(fd, F_SETFL, O_NONBLOCK);

     //==================================================================
     //                             Error Handling
     //==================================================================

            if (fd < 0)
      {
      printf("Serial open error %d %s\n", errno, strerror(errno));
          }
      printf("\n");

    printf("\n==================================================\n");

   //==================================================================
   //                 Get the current options for the port...
   //==================================================================

    tcgetattr(fd, &options);


         //==================================================================
    //                Set the baud rates to 115200...
   //==================================================================


    cfsetispeed(&options, B115200);
    cfsetospeed(&options, B115200);

    //=================================================================
   // Enable the receiver and set local mode..
  //==================================================================

    options.c_cflag |= (CLOCAL | CREAD);

//==================================================================    
// Set the new options for the port...
//==================================================================

     tcsetattr(fd, TCSANOW,&options);

      while(1)
        {  



      write(fd,s,strlen((char*)s));   
      sleep(1);

      len = read(fd,res,100);  
      if (len < 0)
       {   
         if (errno == EAGAIN)
         {         
               continue;
         }
         else
         { 
             printf("read error %d %s\n", errno, strerror(errno));
         } 
       }
     else
      {                   
        res[len < 100 ? len:100] ='\0';
        printf("read %d chars: %s\n",len, res);
      } 
    }
     close(fd);
    } 

我哪里错了。

感谢并致以问候

EN

回答 2

Stack Overflow用户

发布于 2013-08-27 05:43:25

看起来文件描述符是以非阻塞(fcntl(fd, F_SETFL, O_NONBLOCK);)的形式打开的。如果要等待读取数据,则必须执行某些阻塞操作。

您可以使文件描述符阻塞,或者使用像select这样的异步管理器。

票数 1
EN

Stack Overflow用户

发布于 2013-08-27 05:44:59

由于您使您的文件描述符非阻塞(两次),您必须作为系统等待之间的步骤。这样做的一个常见方法是select系统调用,您可以使用该调用等待文件描述符中的某些内容。

可以这样做:

代码语言:javascript
复制
write(...);

fd_set poll_set;
FD_ZERO(&poll_set);
FD_SET(fd, &poll_set);

/* Wait, with no timeout, for something to be readable */
int rc = select(fd + 1, &poll_set, NULL, NULL, NULL);
if (rc == -1)
{
    perror("select");
}
else
{
    /* Continue to next step, where you read */
}

还要注意的是,在第一次尝试中,读取调用实际上可能不会接收到完整的消息。您可能需要多次阅读才能得到完整的消息。如果您的消息大小固定,则在循环中读取,同时减少要读取的字节数,直到收到完整的消息为止。如果您的消息有消息结束标记,则逐字节读取,直到收到为止。如果您的消息包含具有消息大小的标头,那么请使用第一个固定大小的读取方法两次,一次用于获取消息头,一次用于获取数据。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18457772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档