使用 nfs rootfs 读取 tty 时出现问题
Issue when reading tty with nfs rootfs
对于嵌入式设备(内核 3.14 和带有 OpenEmbedded 的 rootfs),我开发了一个软件来读取 tty 驱动程序上的数据。当我在电路板上测试时,该软件运行正常。
如果我为 rootfs 使用 nfs 服务器,则软件会卡在读取 tty 文件的循环中。我不能用 'ctrl+c' 出去,我不能在控制台上写,我有这样的消息“nfs:服务器 192.168.1.40 没有响应,仍在尝试”
有人知道这个问题吗?
谢谢
我的软件:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/poll.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#define FALSE 0
#define TRUE 1
int print_help (int argc, char *argv[])
{
printf("Test program for uart reception\n");
printf("Usage :\n");
printf("\t%s [-h -D -c]\n", argv[0]);
printf("\t-D : use this tty device\n");
printf("\t-c : control data to extract the trame\n");
printf("\t-h : print help\n");
return 0;
}
int wait_flag = TRUE ;
void signal_handler_IO (int status)
{
//printf("received data from UART.\n");
wait_flag = FALSE;
}
/*
* The values for speed are B115200, B230400, B9600, B19200, B38400, B57600,
* B1200, B2400, B4800, etc. The values for parity are 0 (meaning no parity),*
* PARENB|PARODD (enable parity and use odd), PARENB (enable parity and use even),
* PARENB|PARODD|CMSPAR (mark parity), and PARENB|CMSPAR (space parity).
*/
int set_interface_attribs (int fd, int speed, int parity)
{
struct sigaction saio;
struct termios tty;
memset (&tty, 0, sizeof tty);
/***/
saio.sa_handler = signal_handler_IO;
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO, &saio, NULL);
fcntl (fd, F_SETFL, FNDELAY|FASYNC);
fcntl (fd, F_SETOWN, getpid());
/***/
if (tcgetattr (fd, &tty) != 0)
{
printf("error from tcgetattr\n");
return -1;
}
cfsetospeed (&tty, speed);
cfsetispeed (&tty, speed);
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
// disable IGNBRK for mismatched speed tests; otherwise receive break
// as [=10=]0 chars
tty.c_iflag &= ~IGNBRK; // disable break processing
tty.c_lflag = 0; // no signaling chars, no echo,
// no canonical processing
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
// enable reading
tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
tty.c_cflag |= parity;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
if (tcsetattr (fd, TCSANOW, &tty) != 0)
{
printf("error from tcsetattr\n");
return -1;
}
return 0;
}
/*
* "Blocking" sets whether a read() on the port waits for the specified number
* of characters to arrive. Setting no blocking means that a read() returns
* however many characters are available without waiting for more, up to the
* buffer limit.
*/
void set_blocking (int fd, int should_block)
{
struct termios tty;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0)
{
printf ("error from tggetattr\n");
return;
}
tty.c_cc[VMIN] = should_block ? 1 : 0;
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
if (tcsetattr (fd, TCSANOW, &tty) != 0)
printf ("error setting term attributes\n");
}
int main(int argc, char *argv[]) {
int i, j, k;
int fd;
char c;
signed char index_trame = -1;
char trame[6];
char initChaine[30] = "Frame received on uart :";
char *ttyDevice = "/dev/ttyAPP0";
char chaineCar[100];
char receptCar[6];
char buf[255];
char processData[512];
char restofData[6];
int sizeofData = 0;
char ctrl_trame = 0;
int loop = 0;
int ret = 0;
int count = 0;
FILE* saveFile = NULL;
/* Parse arguments */
if (argc < 0 || argc > 4) {
printf("Invalid number of argument\n");
print_help(argc, argv);
return 0;
}
j = 0;
for (i=1; i<argc; i++) {
if (argv[i][0] == '-') {
for (k=1; argv[i][k]; k++) {
switch (argv[i][k]) {
case 'D':
ttyDevice = argv[i+1];
printf("Use %s device\n",ttyDevice);
break;
case 'c':
ctrl_trame = 1;
break;
case 'h':
print_help(argc, argv);
break;
default:
printf("Wrong option: -%c\n", argv[i][k]);
print_help(argc, argv);
return 0;
}
}
} else {
}
j ++;
}/**/
/*run program*/
printf(" Read serial port V0.6\n");
saveFile = fopen("receptUart.txt", "w+");
index_trame = 0;
/* Ouverture de la liaison serie */
if ( (fd=open(ttyDevice, O_RDONLY | O_NOCTTY | O_SYNC)) == -1 ) {
printf("error open %s\n", ttyDevice);
return -1;
}
set_interface_attribs (fd, B2400, 0);
set_blocking (fd, 1);
do {
if (wait_flag == FALSE) {
ret = read(fd, buf, 255);
if (ctrl_trame) {
for (i=0;i<ret;i++)
processData[sizeofData+i] = buf[i];
sizeofData += ret;
for (i=0;i<sizeofData;i++) {
if ((sizeofData - i) < 6) {
break;
}
else if (processData[i] == 0xfa) {
count++;
printf ("Received frame n %d :", count);
for (j=0;j<6;j++) {
trame[j]=processData[i];
printf(" h%02x", processData[i]);
i++;
}
i--;
printf("\n");
}
}
for(j=i;j<sizeofData;j++)
processData[j-i] = processData[j];
sizeofData -= i;
}
else {
printf ("%i data received :", ret);
for (i=0;i<ret;i++) {
printf(" h%02x", buf[i]);
}
printf("\n");
}
wait_flag = TRUE;
}
}
while (1);
close(fd);
printf("GoodBye\n");
return EXIT_SUCCESS;
}
我发现了问题:devicetree 上的设置有问题。
UART 端口设置为使用 CTS/RTS 线路,以太网 PHY 连接到 CTS/RTS 引脚以进行控制。然后这个引脚被用于 2 个驱动程序,其中一个崩溃了。
我更改了 UART 设置,它起作用了
对于嵌入式设备(内核 3.14 和带有 OpenEmbedded 的 rootfs),我开发了一个软件来读取 tty 驱动程序上的数据。当我在电路板上测试时,该软件运行正常。 如果我为 rootfs 使用 nfs 服务器,则软件会卡在读取 tty 文件的循环中。我不能用 'ctrl+c' 出去,我不能在控制台上写,我有这样的消息“nfs:服务器 192.168.1.40 没有响应,仍在尝试”
有人知道这个问题吗?
谢谢
我的软件:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/poll.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#define FALSE 0
#define TRUE 1
int print_help (int argc, char *argv[])
{
printf("Test program for uart reception\n");
printf("Usage :\n");
printf("\t%s [-h -D -c]\n", argv[0]);
printf("\t-D : use this tty device\n");
printf("\t-c : control data to extract the trame\n");
printf("\t-h : print help\n");
return 0;
}
int wait_flag = TRUE ;
void signal_handler_IO (int status)
{
//printf("received data from UART.\n");
wait_flag = FALSE;
}
/*
* The values for speed are B115200, B230400, B9600, B19200, B38400, B57600,
* B1200, B2400, B4800, etc. The values for parity are 0 (meaning no parity),*
* PARENB|PARODD (enable parity and use odd), PARENB (enable parity and use even),
* PARENB|PARODD|CMSPAR (mark parity), and PARENB|CMSPAR (space parity).
*/
int set_interface_attribs (int fd, int speed, int parity)
{
struct sigaction saio;
struct termios tty;
memset (&tty, 0, sizeof tty);
/***/
saio.sa_handler = signal_handler_IO;
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO, &saio, NULL);
fcntl (fd, F_SETFL, FNDELAY|FASYNC);
fcntl (fd, F_SETOWN, getpid());
/***/
if (tcgetattr (fd, &tty) != 0)
{
printf("error from tcgetattr\n");
return -1;
}
cfsetospeed (&tty, speed);
cfsetispeed (&tty, speed);
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
// disable IGNBRK for mismatched speed tests; otherwise receive break
// as [=10=]0 chars
tty.c_iflag &= ~IGNBRK; // disable break processing
tty.c_lflag = 0; // no signaling chars, no echo,
// no canonical processing
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
// enable reading
tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
tty.c_cflag |= parity;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
if (tcsetattr (fd, TCSANOW, &tty) != 0)
{
printf("error from tcsetattr\n");
return -1;
}
return 0;
}
/*
* "Blocking" sets whether a read() on the port waits for the specified number
* of characters to arrive. Setting no blocking means that a read() returns
* however many characters are available without waiting for more, up to the
* buffer limit.
*/
void set_blocking (int fd, int should_block)
{
struct termios tty;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0)
{
printf ("error from tggetattr\n");
return;
}
tty.c_cc[VMIN] = should_block ? 1 : 0;
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
if (tcsetattr (fd, TCSANOW, &tty) != 0)
printf ("error setting term attributes\n");
}
int main(int argc, char *argv[]) {
int i, j, k;
int fd;
char c;
signed char index_trame = -1;
char trame[6];
char initChaine[30] = "Frame received on uart :";
char *ttyDevice = "/dev/ttyAPP0";
char chaineCar[100];
char receptCar[6];
char buf[255];
char processData[512];
char restofData[6];
int sizeofData = 0;
char ctrl_trame = 0;
int loop = 0;
int ret = 0;
int count = 0;
FILE* saveFile = NULL;
/* Parse arguments */
if (argc < 0 || argc > 4) {
printf("Invalid number of argument\n");
print_help(argc, argv);
return 0;
}
j = 0;
for (i=1; i<argc; i++) {
if (argv[i][0] == '-') {
for (k=1; argv[i][k]; k++) {
switch (argv[i][k]) {
case 'D':
ttyDevice = argv[i+1];
printf("Use %s device\n",ttyDevice);
break;
case 'c':
ctrl_trame = 1;
break;
case 'h':
print_help(argc, argv);
break;
default:
printf("Wrong option: -%c\n", argv[i][k]);
print_help(argc, argv);
return 0;
}
}
} else {
}
j ++;
}/**/
/*run program*/
printf(" Read serial port V0.6\n");
saveFile = fopen("receptUart.txt", "w+");
index_trame = 0;
/* Ouverture de la liaison serie */
if ( (fd=open(ttyDevice, O_RDONLY | O_NOCTTY | O_SYNC)) == -1 ) {
printf("error open %s\n", ttyDevice);
return -1;
}
set_interface_attribs (fd, B2400, 0);
set_blocking (fd, 1);
do {
if (wait_flag == FALSE) {
ret = read(fd, buf, 255);
if (ctrl_trame) {
for (i=0;i<ret;i++)
processData[sizeofData+i] = buf[i];
sizeofData += ret;
for (i=0;i<sizeofData;i++) {
if ((sizeofData - i) < 6) {
break;
}
else if (processData[i] == 0xfa) {
count++;
printf ("Received frame n %d :", count);
for (j=0;j<6;j++) {
trame[j]=processData[i];
printf(" h%02x", processData[i]);
i++;
}
i--;
printf("\n");
}
}
for(j=i;j<sizeofData;j++)
processData[j-i] = processData[j];
sizeofData -= i;
}
else {
printf ("%i data received :", ret);
for (i=0;i<ret;i++) {
printf(" h%02x", buf[i]);
}
printf("\n");
}
wait_flag = TRUE;
}
}
while (1);
close(fd);
printf("GoodBye\n");
return EXIT_SUCCESS;
}
我发现了问题:devicetree 上的设置有问题。 UART 端口设置为使用 CTS/RTS 线路,以太网 PHY 连接到 CTS/RTS 引脚以进行控制。然后这个引脚被用于 2 个驱动程序,其中一个崩溃了。 我更改了 UART 设置,它起作用了