测试程序之UART 232/485适用于Android/Linux

简介: 测试程序之UART 232/485适用于Android/Linux

当时写这个的初衷是因为在调试Linux系统 , 串口测试费劲 通过echo/cat 有些功能受限制。

所以就搞了个测试程序 , Android可以不用这个 , 大把的测试工具。

程序功能介绍

这个程序是用来实现串口通信的。它接受三个参数,分别是通信模式(232或485)、串口设备名和波特率。它会根据参数的设置,打开指定的串口,并设置相应的属性。然后,它会创建一个子进程,用于从串口读取数据,并在标准输出上显示。父进程则用于从标准输入读取用户输入的内容,并发送到串口。用户可以输入文本或十六进制字符串,程序会自动识别并转换成字节序列。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
 
#define MODE_232 1
#define MODE_485 2
 
int open_serial_port(const char *port, int baud_rate, int mode)
{
    struct termios tty;
    memset(&tty, 0, sizeof(tty));
 
    int fd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (fd < 0) {
        perror("open");
        return -1;
    }
 
    if (tcgetattr(fd, &tty) != 0) {
        perror("tcgetattr");
        close(fd);
        return -1;
    }
 
    cfsetospeed(&tty, baud_rate);
    cfsetispeed(&tty, baud_rate);
 
    // 设置控制模式(本地连接,接受使能)
    tty.c_cflag |= (CLOCAL | CREAD);
 
    // 设置数据位
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;
 
    // 设置奇偶校验位
    tty.c_cflag &= ~PARENB;
    tty.c_iflag &= ~INPCK;
 
    // 设置停止位数
    tty.c_cflag &= ~CSTOPB;
 
    // 设置等待时间和最小字符数(对应VTIME和VMIN两个参数),这里设为 10 秒和 0 个字符
    tty.c_cc[VTIME] = 100;
    tty.c_cc[VMIN] = 0;
 
    if (mode == MODE_485) {
        // 设置为RS485模式
        tty.c_cflag |= CRTSCTS | CLOCAL;
        tty.c_iflag &= ~(IXON | IXOFF | IXANY);
    } else if (mode == MODE_232) {
        // 设置为RS232模式
        tty.c_cflag &= ~CRTSCTS;
        tty.c_iflag |= (IXON | IXOFF | IXANY);
    }
 
    // 清空输入输出缓冲区
    tcflush(fd, TCIOFLUSH);
 
    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        perror("tcsetattr");
        close(fd);
        return -1;
    }
 
    return fd;
}
 
void read_serial_port(int fd)
{
    char buf[256];
    int n;
 
    while (1) {
        memset(buf, 0, sizeof(buf));
        n = read(fd, buf, sizeof(buf));
        if (n > 0) {
            printf("读到: %s", buf);
        }
    }
}
void write_serial_port(int fd)
{
    char buf[256];
    int n;
 
    while (1) {
        printf("请输入发送内容:");
        fgets(buf, sizeof(buf), stdin);
        n = strlen(buf);
 
        if (n > 0) {
            // 去掉最后的换行符
            if (buf[n-1] == '\n') {
                buf[n-1] = '\0';
                n--;
            }
 
            // 判断输入的字符串是否是十六进制格式
            int is_hex = 1;
            int i;
            for (i = 0; i < n; i++) {
                if ((buf[i] >= '0' && buf[i] <= '9')
                    || (buf[i] >= 'a' && buf[i] <= 'f')
                    || (buf[i] >= 'A' && buf[i] <= 'F')) {
                    continue;
                } else if (buf[i] == ' ') {
                    continue;
                } else {
                    is_hex = 0;
                    break;
                }
            }
 
            if (is_hex) {
                // 将输入的十六进制字符串转换成字节序列
                unsigned char data[128];
                int j = 0;
                for (i = 0; i < n; i++) {
                    if (buf[i] == ' ') {
                        continue;
                    }
 
                    sscanf(&buf[i], "%02X", &data[j]);
                    j++;
                    i++;
                }
                n = j;
                if (n > 0) {
                    n = write(fd, data, n);
                    if (n < 0) {
                        perror("write");
                    } else {
                        printf("hex发送成功\n");
                    }
                }
            } else {
                // 直接将输入的文本发送到串口
                n = write(fd, buf, n);
                if (n < 0) {
                    perror("write");
                } else {
                    printf("txt发送成功\n");
                }
            }
        }
    }
}
int main(int argc, char *argv[])
{
    if (argc != 4) {
        printf("Usage: %s [mode] [serial port] [baud rate]\n", argv[0]);
        return 1;
    }
 
    int mode;
    if (strcmp(argv[1], "232") == 0) {
        mode = MODE_232;
    } else if (strcmp(argv[1], "485") == 0) {
        mode = MODE_485;
    } else {
        printf("Invalid mode: %s\n", argv[1]);
        return 1;
    }
 
    const char *port = argv[2];
    int baud_rate = atoi(argv[3]);
 
    int fd = open_serial_port(port, baud_rate, mode);
    if (fd < 0) {
        fprintf(stderr, "Failed to open serial port %s with baud rate %d\n", port, baud_rate);
        return 1;
    }
 
    printf("Serial port %s opened successfully with baud rate %d and mode %d\n", port, baud_rate, mode);
 
    pid_t pid = fork();
    if (pid == 0) {
    // 子进程用于读取数据
    read_serial_port(fd);
} else if (pid > 0) {
    // 父进程用于写数据
    write_serial_port(fd);
} else {
    perror("fork");
    return 1;
}
 
close(fd);
 
return 0;
}

使用示例

要编译这个程序,需要在终端中输入:

./gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc  -o serial serial.c

要运行这个程序,需要在终端中输入:

./serial [mode] [serial port] [baud rate]

例如:

./serial 232 /dev/ttyUSB0 115200 # 使用RS232模式打开/dev/ttyUSB0串口,并设置波特率为115200
./serial 485 /dev/ttyS0 9600 # 使用RS485模式打开/dev/ttyS0串口,并设置波特率为9600

然后就可以看到类似下面的输出:

Serial port /dev/ttyUSB0 opened successfully with baud rate 115200 and mode 232
请输入发送内容:Hello world!
txt发送成功
读到: Hello world!
请输入发送内容:01 02 03 04 05
hex发送成功
读到: 01 02 03 04 05



相关文章
|
4天前
|
消息中间件 分布式计算 Java
Linux环境下 java程序提交spark任务到Yarn报错
Linux环境下 java程序提交spark任务到Yarn报错
47 4
|
28天前
|
存储 消息中间件 人工智能
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
124 10
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
|
安全 JavaScript 前端开发
AppSpider 7.5.020 发布 - Web 应用程序安全测试
AppSpider 7.5.020 for Windows - Web 应用程序安全测试
37 0
|
28天前
|
Java 测试技术 数据安全/隐私保护
通过yaml文件配置自动化测试程序
通过yaml文件可以将自动化测试环境,测试数据和测试行为分开,请看一下案例
49 4
|
5月前
|
监控 安全 测试技术
【01】卓伊凡收到冒充税务机关的诈骗程序-决定在沙盒Sandbox环境中运行测试下-广大企业同胞们注意防诈骗
【01】卓伊凡收到冒充税务机关的诈骗程序-决定在沙盒Sandbox环境中运行测试下-广大企业同胞们注意防诈骗
154 14
【01】卓伊凡收到冒充税务机关的诈骗程序-决定在沙盒Sandbox环境中运行测试下-广大企业同胞们注意防诈骗
|
7月前
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
1509 77
|
6月前
|
安全 测试技术 Linux
Acunetix v25.4 发布 - Web 应用程序安全测试
Acunetix v25.4 (Linux, Windows) - Web 应用程序安全测试
190 3
Acunetix v25.4 发布 - Web 应用程序安全测试
|
5月前
|
安全 Devops 测试技术
AppSpider 7.5.018 for Windows - Web 应用程序安全测试
AppSpider 7.5.018 for Windows - Web 应用程序安全测试
108 0
AppSpider 7.5.018 for Windows - Web 应用程序安全测试
|
8月前
|
安全 JavaScript Java
AppSpider Pro 7.5.015 for Windows - Web 应用程序安全测试
AppSpider Pro 7.5.015 for Windows - Web 应用程序安全测试
110 12
AppSpider Pro 7.5.015 for Windows - Web 应用程序安全测试
|
7月前
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。

热门文章

最新文章