用select函数实现Linux串口通信 (linux 串口 select)

随着计算机技术逐渐普及,串口通信逐渐成为计算机与外设之间数据交换的常用方式。在Linux系统中,使用串口通信可以通过串口设备文件进行操作。

然而,Linux中的串口通信并非一件易事,特别是在处理多个串口设备的情况下。在这种情况下,使用select函数可有效地提高串口通信的效率和稳定性。

本文将介绍如何使。

一、select函数简介

select函数是Linux提供的一种I/O多路复用机制,通过该函数可同时监听多个文件描述符的读写状态,当某个文件描述符就绪(可以读写)时,select函数会通知应用程序进行相应的操作。

select函数的原型为:

“`c

int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set * exceptfds, struct timeval *timeout);

“`

其中,nfds为要监听的文件描述符的数量,readfds、writefds、exceptfds是三个,分别包含了要监听的文件描述符的读、写、异常情况的文件描述符,timeout为用于设置超时等待的时间。

2、使用select函数实现串口通信

对于串口通信来说,每个串口设备都有一个单独的文件描述符(file descriptor)与之对应,我们可以通过打开串口设备文件得到该描述符。这些描述符可以通过select函数统一进行管理,以便在需要的时候监听它们的读写情况。

以下是使的基本步骤:

(1)打开串口设备

在使用select函数之前,我们需要首先打开串口设备,并将其配置为合适的工作模式。具体的打开串口及配置方法可参考相关的Linux开发书籍,这里不再赘述。

(2)在select函数中添加要监听的文件描述符

在打开串口设备后,需要将该设备的文件描述符添加到select函数中进行监听。首先需要创建一个fd_set类型的。该结构体实为一个位掩码,用于标志要监听的文件描述符。其定义如下:

“`c

typedef struct {

unsigned long fds_bits[FD_SETSIZE / __NFDBITS];

} fd_set;

“`

其中,FD_SETSIZE为的更大值(通常为1024),__NFDBITS为每个long型数据可以存储的位数,所以fds_bits数组的大小为FD_SETSIZE / __NFDBITS。

将文件描述符添加到fd_set中可通过FD_SET宏实现,例如:

“`c

fd_set read_set;

FD_ZERO(&read_set); //清空

FD_SET(fd, &read_set); //添加fd到中

“`

以上代码将读取串口数据用到的文件描述符fd添加到了read_set中。

(3)调用select函数进行监听

将文件描述符添加到fd_set后,接下来需要在select函数中使用该进行监听。此时,select函数将会阻塞进程,等待任一一个文件描述符就绪。

以下是一个简单的select函数调用示例:

“`c

fd_set read_set;

FD_ZERO(&read_set);

FD_SET(fd, &read_set);

//timeout为超时时间

struct timeval timeout;

timeout.tv_sec = 1;

timeout.tv_usec = 0;

int ret = select(fd + 1, &read_set, NULL, NULL, &timeout);

if (ret == -1) {

perror(“select”);

}

else if (ret > 0) {

//有数据可读

}

else {

//超时

}

“`

上述代码将串口文件描述符添加到read_set中,并在timeout时间内等待串口数据到来。如果串口数据准备就绪,select函数将返回大于0的值,此时可以进行读取操作;如果超时时间到达,select函数将返回0。

(4)读取串口数据

当select函数返回大于0的值时,表示有串口数据已经准备就绪。此时,我们可以通过read函数读取数据并进行相应的处理。

读取串口数据的具体操作可参照Linux串口开发相关文档,这里不再赘述。

二、

使用select函数可以有效地简化Linux系统中的串口通信代码,提高系统的性能和稳定性。需要注意的是,当使用select函数实现串口通信时,需要在串口设备打开后将其文件描述符添加到fd_set中,同时还需要排除串口设置过程中的输入/输出操作。

在Linux系统中实现串口通信时,使用select函数能为我们带来诸多好处,值得开发者们一试。

相关问题拓展阅读:

如何查看linux下串口是否可用?串口名称等?

分析如下:

1、查看串口是否可用,可以对串口发送数据比如对com1口,echo lyjie126 > /dev/ttyS0。

2、查看串口名称使用 ls -l /dev/ttyS* 一般情况下串口的名称全部在dev下面,如果你没有外插串口卡的话默认是dev下的ttyS* ,一般ttyS0对应com1,ttyS1对应com2,当然也不一定是必然的;

3、查看串口驱动:cat /proc/tty/drivers/serial。

4、查看串口设备:dmesg | grep ttyS*。

扩展资料

串口控制器顾名思义,就是可通过串口实现控制功能的一台控制器。即由上位机通过串口发送特定协议格式的指令给控制器,进而来控制外围设备或器件,也叫单片机串口控制器。

串口控制器就是1台写入了串口通信程序的单片机控制器,有2种工作模式:

1)上位机监控模式:可由上位机串口控制,实现串口监控;

2)脱机控制模式:在通过上位机设置好相关参数后,也可脱离上位机进行独立控制。

串口控制器就是1台写入了串口通信程序的单片机控制器,有2种工作模式:

1)上位机监控模式:可由上位机串口控制,实现串口监控;

2)脱机控制模式:在通过上位机设置好相关参数后,也可脱离上位机进行独立控制。

参考资料来源:

百度百科:串口控制器

linux管道和串口

在游手linux下用

# include

# include

# include

# include

# include

# include

# include

# include

# include

int CommFd, TtyFd;

static void Error(const char *Msg)

{

fprintf (stderr, “%s\n”, Msg);

fprintf (stderr, “strerror() is %s\n”, strerror(errno));

exit(1);

}

static void Warning(const char *Msg)

{

fprintf (stderr, “Warning: %s\n”, Msg);

}

static int SerialSpeed(const char *SpeedString)

{

int SpeedNumber = atoi(SpeedString);

# define TestSpeed(Speed) if (SpeedNumber == Speed) return B##Speed

TestSpeed(1200);

TestSpeed(2400);

TestSpeed(4800);

TestSpeed(9600);

TestSpeed(19200);

TestSpeed(38400);

TestSpeed(57600);

TestSpeed(115200);

TestSpeed(230400);

Error(“Bad speed”);

return -1;

}

static void PrintUsage(void)

{

fprintf(stderr, “comtest – interactive program of comm port\n”);

fprintf(stderr, “press 3 times to quit\n\n”);

fprintf(stderr, “Usage: comtest \n”);

fprintf(stderr, “bit\唤磨扮n”);

fprintf(stderr, “x hex mode\n”);

fprintf(stderr, “o output to stdout too\n”);

fprintf(stderr, “c stdout output use color\n”);

fprintf(stderr, “和灶h print this help\n”);

exit(-1);

}

static inline void WaitFdWriteable(int Fd)

{

fd_set WriteSetFD;

FD_ZERO(&WriteSetFD);

FD_SET(Fd, &WriteSetFD);

if (select(Fd + 1, NULL, &WriteSetFD, NULL, NULL) = (y)) ? (x) : (y) )

if (select(max(CommFd, TtyFd) + 1, &ReadSetFD, NULL, NULL, NULL) = 3)

goto ExitLabel;

} else

EscKeyCount = 0;

}

}

}

ExitLabel:

if (tcsetattr(TtyFd, TCSANOW, &BackupTtyAttr)

Error(“Unable to set tty”);

return 0;

}

关于linux 串口 select的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。


数据运维技术 » 用select函数实现Linux串口通信 (linux 串口 select)