1.实验目的
通过编写多路复用式串口读写,进一步理解多路复用函数的用法,同时更加熟练地掌握Linux设备文件的读写方法。
2.实验内容
本实验中,实现两台机器(宿主机和目标板)之间的串口通信,而且每台机器均可以发送数据和接收数据。 除了串口设备名称不同(宿主机上使用串口1:/dev/ttyS0,而在目标板上使用串口2:/dev/ttyS1),两台机器上的程序基本相同。
首先,程序打开串口设备文件并进行相关配置,调用select()函数,使它等待从标准输入(终端)文件中的输入数据及从串口设备的输入数据。如果有标准输入文件上的数据,则写入到串口,使对方读取。如果有串口设备上的输入数据,则将数据写入到普通文件中。
3.实验步骤
(1)画出流程图。图2.6所示为程序流程图,两台机器上的程序使用同样的流程图。
图2.6 宿主机/目标板程序的流程图
(2)编写代码。编写宿主机和目标板上的代码,在这些程序中用到的open_port()和set_com_config()函数请参照后续章节所述,这里只列出宿主机上的代码。
/* com_host.c */
#include
#include
#include
#include
#include
#include
#include
#include
#include "uart_api.h"
int main(void)
{
int fds[SEL_FILE_NUM], recv_fd, maxfd;
char buff[BUFFER_SIZE];
fd_set inset,tmp_inset;
struct timeval tv;
unsigned loop = 1;
int res, real_read, i;
/* 将从串口读取的数据写入到这个文件中 */
if ((recv_fd = open(RECV_FILE_NAME, O_CREAT|O_WRONLY, 0644)) < 0)
{
perror("open");
return 1;
}
fds[0] = STDIN_FILENO; /* 标准输入 */
if ((fds[1] = open_port(HOST_COM_PORT)) < 0) /* 打开串口 */
{
perror("open_port");
return 1;
}
if (set_com_config(fds[1], 115200, 8, 'N', 1) < 0) /* 配置串口 */
{
perror("set_com_config");
return 1;
}
FD_ZERO(&inset);
FD_SET(fds[0], &inset);
FD_SET(fds[1], &inset);
maxfd = (fds[0] > fds[1])?fds[0]:fds[1];
tv.tv_sec = TIME_DELAY;
tv.tv_usec = 0;
printf("Input some words(enter 'quit' to exit):
");
while (loop && (FD_ISSET(fds[0], &inset) || FD_ISSET(fds[1], &inset)))
{
tmp_inset = inset;
res = select(maxfd + 1, &tmp_inset, NULL, NULL, &tv);
switch(res)
{
case -1: /* 错误 */
{
perror("select");
loop = 0;
}
break;
case 0: /* 超时 */
{
perror("select time out");
loop = 0;
}
break;
default:
{
for (i = 0; i < SEL_FILE_NUM; i++)
{
if (FD_ISSET(fds[i], &tmp_inset))
{
memset(buff, 0, BUFFER_SIZE);
/* 读取标准输入或者串口设备文件 */
real_read = read(fds[i], buff, BUFFER_SIZE);
if ((real_read < 0) && (errno != EAGAIN))
{
loop = 0;
}
else if (!real_read)
{
close(fds[i]);
FD_CLR(fds[i], &inset);
}
else
{
buff[real_read] = '