嵌入式linux系统串口只能接收到一次数据
环境如下:开发板使用/dev/ttyS0 通过串口与WINDOWS XP主机通信,主机使用调试助手。
在开发板上 配置参数如下:
int set_Parity(int fd, int databits, int stopbits, int parity)
{
struct termios options;
if (tcgetattr(fd, &options) != 0)
{
perror("SetupSerial 1");
return (1);
}
cfmakeraw(&options);
options.c_cflag &= ~CSIZE;
switch (databits)
/*设置数据位数*/
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr, "Unsupported data size\n");
return (1);
}
switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB; /* Clear parity enable */
options.c_iflag &= ~INPCK; /* Enable parity checking */
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
options.c_oflag &= ~OPOST; /*Output*/
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'e':
case 'E':
options.c_cflag |= PARENB; /* Enable parity */
options.c_cflag &= ~PARODD; /* 转换为偶效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'S':
case 's': /*as no parity*/
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr, "Unsupported parity\n");
return (1);
}
/* 设置停止位*/
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr, "Unsupported stop bits\n");
return (1);
}
/* Set input parity option */
if (parity != 'n')
options.c_iflag |= INPCK;
options.c_cc[VTIME] = 0; /* 设置超时15 seconds*/
options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
tcflush(fd, TCIFLUSH);
if (tcsetattr(fd, TCSANOW, &options) != 0)
{
perror("SetupSerial 3");
return (1);
}
return (0);
}
然后调用读取接口(通过select(fd)的方式):
int read_datas_ttyS0(char *rcv_buf, int sec, int usec)
{
int retval;
fd_set rfds;
struct timeval tv;
int st = 0;
int ret = 0;
int pos = 0;
tv.tv_sec = sec;
tv.tv_usec = usec;
while (1)
{
FD_ZERO(&rfds);
FD_SET(g_fdSerialPort, &rfds);
retval = select(g_fdSerialPort + 1, &rfds, NULL, NULL, &tv);
if (retval == -1)
{
return -1; //有错误发生
}
else if (retval)
{
ret = read(g_fdSerialPort, rcv_buf + pos, 1024);
/*log_write(
LOG_LEVEL_TRACK,
"__FILE__:%s __LINE__:%d LEVEL:%d receive data is:%s, length is :%d\n",
__FILE__, __LINE__, LOG_LEVEL_TRACK, rcv_buf, ret);*/
if (ret >= 0)
{
/*back_light(1);
text_out(0, 0, (const unsigned char *) "read data ");
text_out(0, 20, (const unsigned char *) &rcv_buf[3]);
sleep(10);
log_write(
LOG_LEVEL_TRACK,
"__FILE__:%s __LINE__:%d LEVEL:%d receive data is:%s, length is :%d\n",
__FILE__, __LINE__, LOG_LEVEL_TRACK, rcv_buf, ret);*/
pos += ret;
st = checkProtocol(rcv_buf, pos);
if (0 == st) //表示接受到了完整的协议包
{
log_write(
LOG_LEVEL_TRACK,
"__FILE__:%s __LINE__:%d LEVEL:%d protocol is compleate\n",
__FILE__, __LINE__, LOG_LEVEL_TRACK);
return 0;
}
else
{
/*log_write(
LOG_LEVEL_TRACK,
"__FILE__:%s __LINE__:%d LEVEL:%d protocol is not compleate\n",
__FILE__, __LINE__, LOG_LEVEL_TRACK);*/
continue;
}
}
else
{
return -1;
}
}
else //超时
{
//超时之前检查是否已经读取到了完整的协议包
st = checkProtocol(rcv_buf, pos);
/*log_write(
LOG_LEVEL_TRACK,
"__FILE__:%s __LINE__:%d LEVEL:%d timeout from readttys0 st is :%d\n",
__FILE__, __LINE__, LOG_LEVEL_TRACK, pos);*/
if (0 == st) //表示接受到了完整的协议包
{
return 0;
}
else
{
return -2; //被刺监听超时
}
}
} //end while()
}
main()
{
while (g_SystemStatus.getSytemStatus()) //POS系统在线
{
lcd_clear();
back_light(1);
memset(buffer, 0, BUFFER_LENGTH); //清空缓冲区
//读串口
st = read_datas_ttyS0(buffer, 0, TTY_TIMEOUTS); //超时时间为100ms
if (0 == st) //读到指令数据
{
unsigned char txt[20] = "";
sprintf((char *) txt, "st:%d,cmd:%x,len%d", st, buffer[2],
buffer[1]);
back_light(1);
text_out(0, 40, txt);
//write_datas_tty("=====ok====", strlen("=====ok===="));
sleep(3);
log_write(
LOG_LEVEL_TRACK,
"__FILE__:%s __LINE__:%d LEVEL:%d length %d:process the user command :%x\n",
__FILE__, __LINE__, LOG_LEVEL_TRACK, buffer[1], buffer[2]);
//TODO 处理PC发送过来的指令,
//command_process(buffer);
}
else //用户没有命令过来,执行例行的操作
{
unsigned char txt[20] = "";
sprintf((char *) txt, "N:st:%d,cmd:%x,len%d", st, buffer[2],
buffer[1]);
// lcd_clear();
text_out(0, 52, txt);
//write_datas_tty("=====err====", strlen("=====err===="));
sleep(2);
//states_comman_process();
} //end else (no new command serial port )
} //end while(status == is run)
}
问题情况如下:main中只有第一次读取到的数据能接收到,read_datas_ttyS0()返回值为0,第二次以及以后都返回-2,超时,
不知道为什么。但是如果把//write_datas_tty("=====ok====", strlen("=====ok===="));
这个启用,其内部就是对write接口的封装,就又可以读取到第二次PC主机发送过来的数据了,我猜测是不是每次读取数据之前都应该配置下串口??请各位高手帮帮忙!