我正在一台小型Linux服务器(在Beagleboard xM ARM计算机上运行的Ubuntu Server 13.04)上工作,它将在笔记本电脑之间进行无线通信和Arduino通信。我似乎遇到的问题是关于Arduino和Beagleboard之间的通信。该程序将运行一段时间,大约30秒左右,然后它将停止。该程序将继续运行,但该端口显然已冻结。
我正在运行的程序目前只是一个扫描伺服超过一定范围的测试程序。找到了用于设置端口的函数的代码here。
我的程序代码如下,但在单独的线程中找到的代码除外:
#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命令关闭串口。
谢谢!
答案 0 :(得分: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