串口通信picocom源码解析

本文深入解析了串口通信软件Picocom的源码,从main入口开始,详细介绍了参数设置、信号处理、日志初始化、串口初始化等过程。文章重点分析了串口参数设置、DTR和RTS状态设置以及主处理函数loop的工作原理,包括通过select进行文件符集遍历,读取STI和串口数据,以及写入命令到串口的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

串口通信picocom源码解析

一.Main入口分析

picocom.c文件是main入口文件,与其他程序一样,先进行初始化:

int
main (int argc, char *argv[])
{
....
parse_args(argc, argv);//参数设置
establish_signal_handlers();//信号中断处理
r = term_lib_init();//terminal 初始化
...
//日志初始化
log_fd = open(opts.log_filename,
                  O_CREAT | O_RDWR | O_APPEND,
                  S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
...
//串口初始化                  
tty_fd = open(opts.port, O_RDWR | O_NONBLOCK | O_NOCTTY);                  
//这个函数进行串口参数设置
term_set(...)

/******    下面代码进行2次set_dtr_rt();-----------    *****/
/* Set DTR and RTS status, as quickly as possible after opening
   the serial port (i.e. before configuring it) */
set_dtr_rts();
r = term_apply(tty_fd, 0);
if ( r < 0 )
    fatal("failed to config port: %s",
          term_strerror(term_errno, errno));
/* Set DTR and RTS status *again* after configuring the port. On
   some systems term_apply() resets the status of DTR and / or
   RTS */
set_dtr_rts();

/***    ------判断串口读取是否成功,由以下三个参数共同决定--------    ***/
if ( !opts.quiet && !opts.noinit && show_status(1) != 0 )
...    

/*******    ---------主处理函数------------    ******/
ler = loop();

主处理函数 loop()

通过select遍历文件符集(rdset,wrset),参数opts.exit_after是否设置阻塞时间.
注意memmove与memcpy用法区别.

while ( ! sig_exit ) {
....
r = select(tty_fd + 1, &rdset, &wrset, NULL, ptv);
...
n = read(STI, buff_rd, sizeof(buff_rd));//读一遍STI,即terminal,是否有输入指令
...
n = read(tty_fd, &buff_rd, sizeof(buff_rd));//读一边串口,看是否有输出
...
n = write(tty_fd, tty_q.buff, sz);//写入tty_q.buff,即由STI中读取到的命令,写到串口中
...
}
读取STI分析

以下代码中,tty_q_push函数分析用户在STI中的每一个字符,对enter\删除键等等做处理.
tty_q_push 把每一个字符存入tty_q.buff中,

          for ( i = 0; i < n; i++ ) {
            c = buff_rd[i];
            switch (state) {
            case ST_COMMAND:
                if ( c == opts.escape ) {
                    /* pass the escape character down */
                    if ( tty_q_push((char *)&c, 1) != 1 )
                        fd_printf(STO, "\x07");
                } else {
                    /* process command key */
                    if ( do_command(c) )
                        /* picocom exit */
                        return LE_CMD;
                }
                state = ST_TRANSPARENT;
                break;
            case ST_TRANSPARENT:
                if ( ! opts.noescape && c == opts.escape )
                    state = ST_COMMAND;
                else
                    if ( tty_q_push((char *)&c, 1) != 1 )
                        fd_printf(STO, "\x07");
                break;
            default:
                assert(0);
                break;
            }
        }
<think>我们正在讨论picocom串口工具的使用。用户提到“picocom 登录串口发送指令”,这通常指的是使用picocom这个串口终端程序来连接串口设备(如嵌入式设备、路由器等),并通过该终端发送指令。 由于问题比较简短,我们首先解释一下picocom的基本用法,然后给出一个发送指令的例子。 注意:picocom在退出时可能需要特殊按键(如Ctrl+A, Ctrl+X)来退出。 基本命令格式: picocom [选项] <串口设备> 常用选项: -b: 设置波特率(如9600, 19200, 38400, 115200等) -p: 设置奇偶校验(n为无,e为偶校验,o为奇校验) -d: 数据位(通常为8) -r: 流控(通常不用,所以设为none) --emap: 特殊字符映射(例如将默认的退出键Ctrl+A映射为其他,但通常不用改) 示例:以115200波特率连接/dev/ttyUSB0 picocom -b 115200 /dev/ttyUSB0 连接后,就可以直接输入指令(直接敲命令,回车)发送给串口设备了。 退出picocom:先按Ctrl+A,然后按Ctrl+X。 但是,有时候我们可能需要发送文件或者预先编写好的指令,这可以通过在picocom中使用转义序列来实现,但更常见的是使用其他工具(如minicom)的脚本功能。不过picocom也可以结合输入重定向来发送文件。 例如,将指令写入文件commands.txt,然后通过输入重定向发送: picocom -b 115200 /dev/ttyUSB0 < commands.txt 但是注意,这样发送后picocom会退出(因为输入结束)。如果要在发送后保持连接并交互,则不能使用输入重定向。此时,可以考虑使用expect脚本或者picocom的转义序列(但picocom的转义序列主要用于控制自身,如退出等,并不直接支持发送文件)。 另一种方法是使用screen命令(如果可用)或者使用minicom的脚本功能。但既然问题指定picocom,我们可以尝试在picocom中手动输入,或者使用更高级的脚本。 由于问题没有具体说明是手动发送还是自动发送,我们假设用户需要知道如何手动发送指令(即连接后直接输入)以及如何自动发送(通过重定向或脚本)。 因此,我们的回答将包括: 1. 基本连接方法。 2. 手动发送指令的方法(连接后直接输入指令并回车)。 3. 自动发送指令(通过重定向文件)的方法。 注意:自动发送方法在发送完文件内容后picocom会退出,所以适合非交互式场景。 如果用户需要更复杂的交互(如发送指令后根据返回再发送),可能需要使用expect脚本。 下面我们给出一个简单的示例,展示如何通过重定向自动发送指令。 假设我们有一个指令文件commands.txt,内容为: ls pwd 然后执行: picocom -b 115200 /dev/ttyUSB0 < commands.txt 这样就会依次发送ls和pwd指令(注意:每行指令后面需要换行符,因为串口设备通常以换行符作为命令结束)。 但是,由于串口设备可能有不同的命令提示符和响应时间,自动发送可能无法等待上一条命令执行完再发送下一条。因此,这种方法适用于对时序要求不高的场景。 如果需要更精确的控制,建议使用expect脚本。 现在,我们按照要求,在回答的最后提出3-5个相关问题。</think>### picocom 登录串口发送指令的方法 使用 **picocom** 连接串口设备并发送指令的步骤如下: 1. **安装 picocom**(如未安装): ```bash sudo apt install picocom # Debian/Ubuntu ``` 2. **基本连接命令**: ```bash picocom -b 波特率 -p 奇偶校验 -d 数据位 -r 流控 /dev/tty设备 ``` **常用参数**: - `-b 115200`:波特率(常用值:9600, 19200, 115200) - `-p n`:奇偶校验(`n`无校验, `e`偶校验, `o`奇校验) - `-d 8`:数据位(默认8位) - `-r n`:流控(`n`无流控, `h`硬件流控) - `/dev/ttyUSB0`:串口设备路径(根据实际设备调整) 3. **示例连接命令**: ```bash picocom -b 115200 -p n -d 8 -r n /dev/ttyUSB0 ``` 4. **发送指令**: - 连接成功后,直接输入指令并按回车发送 - 示例:发送 `AT` 指令检测设备响应 ``` AT ``` 5. **退出 picocom**: - 按组合键 `Ctrl+A` → 再按 `Ctrl+X` 安全断开 --- ### 自动发送指令的方法 通过输入重定向批量发送指令: ```bash echo -e "AT\r\nAT+CFUN?\r\n" > commands.txt picocom -b 115200 /dev/ttyUSB0 < commands.txt ``` > **注意**:每条指令需以 `\r\n` 结尾(回车换行符) --- ### 常见问题排查 1. **权限不足**:添加当前用户到 `dialout` 组 ```bash sudo usermod -aG dialout $USER ``` 2. **设备未识别**:检查设备路径(`ls /dev/tty*`) 3. **乱码问题**:确认波特率/校验位与设备匹配
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值