2

我正在开发一个小型 Linux 服务器(在 Beagleboard xM ARM 计算机上运行的 Ubuntu Server 13.04),它将在笔记本电脑和 Arduino 之间进行无线通信。我似乎遇到的问题是关于 Arduino 和 Beagleboard 之间的通信。该程序将运行一段时间,大约 30 秒左右,然后它会停止。该程序将继续运行,但端口显然冻结。

我正在运行的程序目前只是一个测试程序,它将在一定范围内扫描伺服。用于设置端口的函数代码可在此处找到。

我的程序代码如下,除了在单独线程中找到的代码:

    #include <errno.h>
    #include <termios.h>
    #include <stdio.h>
    #include <string.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <iostream>

    using namespace std;

   ...

   int main (int argc, const char* argv[]) {
        cout << "TestIO running...\n";
        char* portname = "/dev/ttyACM0";
        // Open serial port
        int fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);

        // Return error if port cannot be opened
        if (fd < 0)
        {
                cout << "error " << errno << " opening " <<  portname << ": " << strerror (errno) << "\n";
                return -1;
        }

        set_interface_attribs (fd, B9600, 0);   // set speed to 9600 bps, 8n1 (no parity)
        set_blocking (fd, 0);                   // set no blocking

        // Read from serial port
        //char inputBuffer[64];
        //int inputLength = read(fd, inputBuffer, sizeof inputBuffer);

        double output = 575;
        char outputString[255];
        char outputLength;
        int incrimentor = 1;
        char inChar;
        for(;;) {
                if (output >= 675 )
                        incrimentor = -1;
                else if (output <= 375)
                        incrimentor = 1;
                output += incrimentor;

                // Sweep wheels on car, set drive motor to 0
                outputLength = sprintf(outputString, "%0.2f", output);
                write(fd, outputString, outputLength);
                write(fd, ",", 1);
                write(fd, "0", 1);
                write(fd, "\n", 1);

                cout << outputString << "\n";

                // Sleep thread for 5000 uS (5 ms)
                usleep(5000);
        }
        close(fd);
        return 0;
}

稍微不同的是,当程序冻结时,我必须强制它退出代码以关闭端口,因此我无法再次运行程序来测试它。我很好奇是否有人知道如何通过在终端中运行的 Linux 命令关闭串行端口。

谢谢!

4

1 回答 1

0

关于如何退出悬挂程序的第二个问题:

为所有系统调用添加返回值测试通常是一个好主意!

请注意,read()/write()不一定读入/写出与被告知的一样多的数据。

如果进程收到信号,也read()/返回。write()

这里特别将测试结果添加到可能阻塞的调用中(write()):

ssize_t writen(int fd, char * buffer, size_t size)
{
  ssize_t written_total = 0;
  ssize_t written = 0;

  while  (outputLength > written_total)
  {
    written = write(fd, buffer + written_total, size - written_total);
    if (-1 == written)
    {
      if (EINTR == errno)
      {
        /* interupted by signal -> break and leave */
        break;
      }
      elseif ((EAGAIN == errno) || (EWOULDBLOCK == errno))
      {
        continue; /* try again */
      }

      /* another error occured -> log, break and leave */

      break;
    }

    written_total += written;
  }

  if (outputLength > written_total)
  {
    if (-1 = written)
    {
      /* handle error */
    }
    else
    {
      /* notify of interruption */
    }
  }
  else
  {
    /* log succesfully transmission of all data */
  }

  return written_total;
}

int main()
{
  ...

  do
  {
    if (outputLength != writen(fd, outputString, outputLength))
    {
      fprintf(stderr, "writen(fd, outputString, outputLength) failed");
      break;
    }

    if (1 != writen(fd, ",", 1))
    {
      fprintf(stderr, "writen(fd, ",", 1)) failed");
      break;
    }

    if (1 != writen(fd, "0", 1))
    {
      fprintf(stderr, "writen(fd, "0", 1)) failed");
      break;
    }

    if (1 != writen(fd, "\n", 1))
    {
      fprintf(stderr, "writen(fd, "\n", 1)) failed");
      break;
    }
  } while (0);

  if (-1 == close(fd))
  {
    perror("close() failed");
  }

  ...
}

请注意,程序还需要注册一个信号处理程序(SIGUSR1例如),它什么都不做,只是“吃掉”信号。

然后从命令行,您可以通过执行以下操作轻松取消阻止程序:

$ kill <program-pid> -SIGUSR1
于 2013-09-30T13:20:38.210 回答