【linux】一种基于虚拟串口的方式使两个应用通讯

在Linux系统中,两个应用之间通过串口(Serial Port)进行通信是一种常见的通信方式,特别是在嵌入式系统、工业自动化等领域。串口通信通常涉及到对串口设备的配置和读写操作。以下是一个基本的步骤指南,说明如何在Linux中设置两个应用以通过串口进行通信:

1. 确认串口设备

首先,你需要确认你的Linux系统上有哪些串口设备。通常,串口设备在/dev目录下,如/dev/ttyS0、/dev/ttyUSB0等。你可以使用dmesg命令查看系统启动时串口设备的识别信息,或者使用ls /dev/tty*来列出所有tty设备。

2. 配置串口参数

串口通信需要配置一些参数,如波特率(Baud Rate)、数据位(Data Bits)、停止位(Stop Bits)、校验位(Parity)等。在Linux中,你可以使用stty命令来配置这些参数。例如,要将/dev/ttyS0配置为9600波特率,8数据位,1停止位,无奇偶校验,可以使用以下命令:

3. 编写通信程序

接下来,你需要编写两个程序,一个作为发送方,另一个作为接收方。这些程序可以使用Linux系统调用(如open(), read(), write(), close())来操作串口设备。

示例代码(C语言)

发送方(sender.c)

cpp 复制代码
#include <stdio.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <string.h> 


int main() { 
int fd = open("/dev/ttyS0", O_WRONLY); 
if (fd < 0) { 
perror("Error opening serial port"); 
return -1; 
} 


const char *msg = "Hello, Serial Port!"; 
write(fd, msg, strlen(msg)); 


close(fd); 
return 0; 
}

接收方(receiver.c)

cpp 复制代码
#include <stdio.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <termios.h> 


#define BUFFER_SIZE 1024 


int main() { 
int fd = open("/dev/ttyS0", O_RDONLY | O_NOCTTY | O_NDELAY); 
if (fd < 0) { 
perror("Error opening serial port"); 
return -1; 
} 


// 清除非阻塞标志 
fcntl(fd, F_SETFL, 0); 


char buffer[BUFFER_SIZE]; 
int num_bytes = read(fd, buffer, BUFFER_SIZE); 
if (num_bytes < 0) { 
perror("Error reading from serial port"); 
return -1; 
} 


buffer[num_bytes] = '\0'; 
printf("Received: %s\n", buffer); 


close(fd); 
return 0; 
}

4. 编译和运行程序

使用gcc编译你的C程序,并运行它们。确保发送方在接收方之前运行,或者确保接收方能够处理串口数据的到达。

5. 调试

如果通信没有按预期工作,检查以下几点:

  • 串口设备是否正确配置。
  • 串口参数(如波特率)在两个程序中是否一致。
  • 是否有其他程序正在使用同一个串口。
  • 使用dmesg或tail -f /var/log/syslog(取决于你的系统)来查看系统日志,了解是否有错误信息。

通过以上步骤,你应该能够在Linux系统中设置两个应用通过串口进行通信。

另附一段串口测试源码:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>

int main() {
    int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd == -1) {
        perror("open_port: Unable to open /dev/ttyS0 - ");
        return(-1);
    }

    struct termios options;
    tcgetattr(fd, &options);

    // 设置波特率
    cfsetispeed(&options, B9600);
    cfsetospeed(&options, B9600);

    // 设置数据位数
    options.c_cflag &= ~CSIZE; // Mask the character size bits
    options.c_cflag |= CS8;

    // 设置为无奇偶校验位
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;

    // 设置为一个字符一个停止位
    options.c_cflag &= ~CRTSCTS;

    // 应用设置
    tcsetattr(fd, TCSANOW, &options);

    // 写数据
    char *write_buffer = "Hello World";
    write(fd, write_buffer, sizeof(write_buffer));

    // 读数据
    char read_buffer[100];
    read(fd, read_buffer, sizeof(read_buffer));
    printf("Received: %s\n", read_buffer);

    close(fd);
    return 0;
}
相关推荐
IMPYLH9 分钟前
Linux 的时间为什么会被拨回去
linux·运维·服务器
2601_963282771 小时前
寒地窄带通信工程实践:黑龙江哈尔滨对讲机选型、组网与合规运维总结
运维·服务器·网络
叼烟扛炮2 小时前
[Git 实战] 学习笔记:从生成 SSH 密钥到解决 TortoiseGit 推送报错全指南
linux·运维·笔记·git·学习
xbzb2 小时前
OpenStack 网络管理(理论):Linux 网络虚拟化是 Neutron 的地基
linux·服务器·网络·openstack·network·neutron
我要见SA姐13 小时前
GitHub Actions 自动化:5 个真实运维提效案例
运维·数据库·机器学习·oracle·回归
Android系统攻城狮4 小时前
Linux FFmpeg深度解析之avcodec_flush_buffers调用流程与实战(十九)
linux·运维·服务器·ffmpeg·车载音视频·ffmpeg音视频进阶
水饺编程5 小时前
第2章:Linux 基础,解压缩【.tar.bz2】压缩包文件
linux·c语言·汇编
Y3815326625 小时前
用 httpx 写 SerpBase 异步客户端:连接池与超时配置
运维·服务器·数据库
Zevalin爱灰灰5 小时前
Linux入门第二部分(ARM裸机篇) 第二章 Cortex-A7 MPCore架构与ARM汇编基础
linux·汇编·arm开发·嵌入式
倔强的石头1065 小时前
【Linux指南】进程通信系列(七):System V 信号量 —— 同步互斥的内核原语
linux·运维·服务器