Linux 串口编程学习记录(termios.h)

2023-05-16

目录

0、Linux 串口编程简述

1、open() / close() 函数

open() 函数参数说明:

close() 函数参数说明

2、termios 结构体

a、c_cflag 控制模式标志位可选参数(unsigned short,16位)

b、c_iflag 输入模式标志位可选参数(unsigned short,16位)

c、c_oflag 输入模式标志位可选参数(unsigned short,16位)

d、c_lflag 本地模式标志位可选参数(unsigned short,16位)

e、c_cc[NCC] 数组:特殊控制字符

3、tcsetattr() / tcgetatt()函数

4、tcflush() 函数

5、write()/read() 函数

6、ioctl() 函数

7、其他函数tcdrain() / tcflow()


0、Linux 串口编程简述

Linux 上 C++ 的串口编程主要 API 都定义在了在头文件 termios.h 中。Linux 串口与单片机串口本质上是一样的,在初始化阶段都是要设置波特率、停止位、奇偶校验位等属性的。

C++ Linux串口编程的一般流程为:

  1. 使用 open() 函数(POSIX标准函数,需包含头文件 fcntl.h)打开串口;
  2. 设置结构体 termios 中的对应参数(串口的所有属性都在这个结构体里设置,后面会细说);
  3. 调用 tcflush() 函数选择性地清空 I/O 缓冲区中的数据;
  4. 调用 tcsetattr() 函数,并传入 termios 结构体(参数之一)来初始化串口;
  5. 调用 write()/read() 函数(需包含头文件 unistd.h)进行串口的读写;
  6. 调用 close() 函数(需包含头文件 unistd.h)关闭串口。

下面对以上提到的函数和结构体逐一介绍:

1、open() / close() 函数

open() / close() 函数分别定义在头文件 fcntl.h 和 unistd.h 中,是 Linux 中的底层系统调用函数,且都是遵循 POSIX(Portable Operating System Interface of UNIX,可移植操作系统接口) 标准的函数。

Linux 中的所有 open 类的函数比如 fopen()/fclose() 都是在 open() / close() 的基础上封装得到的,因此不管是打开一个串口、一个 socket 还是一个文件,本质上都是通过 open 函数实现的,因为在 Linux 中一切皆文件嘛,以下介绍是对Linux文件通用的,当然也适用于串口操作。可以先看一下 open() / close() 函数的定义:

#incude <fcntl.h>
// 若打开成功则返回新文件描述符 fd(一个整型数),若出错为-1
// 有 两参 和 三参 版本
int open(const char* file, int oflags)
int open(const char* file, int oflags, mode_t mode)

#incude <unistd.h>
// 若关闭成功则返回 0, 否则返回 -1,关闭一个已关闭的描述符会出错
int close(int fd) 

open() 函数参数说明:

文件描述符 fd 是一个整型数,系统是怎么通过这个整型数来操作串口的呢?可以看下这个解释。总的来说,这个返回的整型句柄 fd 其实相当于一个结构体数组的索引,系统可以通过这个索引值对应的结构体来操作相应的串口。Linux 中 fd=0 代表标准输入,fd=1 代表标准输出, fd=2 代表标准错误。

oflag 用来设置一些标志位进而控制文件(或者说串口等)的打开模式

1、O_RDONLY(只读) / O_WRONLY(只写) / O_RDWR(可读可写):这三种参数在使用时只能三选一使用
# 另外还有其他模式可以设置:
2、O_APPEND   : 每次写操作都写入文件的末尾,不影响已存在的数据。
3、O_CREAT    : 如果指定文件不存在,则创建这个文件。使用此选项时,需要同时说明第三个参数mode,用其说明该新文件的存取许可权限。
4、O_EXCL     : 如果要创建的文件已存在,则返回 -1,并且修改errno的值。
5、O_TRUNC    : 如果文件存在,并且以只写/读写方式打开,则清空文件全部内容。
6、O_NOCTTY   : 该标志用于告知系统它不会成为进程的控制终端。如果不指定该标志,任何输入都会影响程序(比如键盘中止信号等)。
7、O_NONBLOCK : 如果路径名指向 FIFO/块文件/字符文件,则把文件的打开和后继 I/O 设置为非阻塞模式(nonblocking mode)。
8、O_NDELAY   : 告诉内核这个程序不关注 DCD 信号线的状态。如果不指定该标志,当 DCD 信号线是空电压值的时候,程序将会进入睡眠。
9、O_SYNC     : 同步方式写入文件
10、O_DSYNC   : 提供同步的I/O数据完整性
11、O_ASYNC   : 当I/O操作可行,产生信号通知进程
12、O_DIRECT  : 无缓冲输入输出

注:O_NDELAY 标志位中出现了 DCD(Data Carrier Detect,载波检测),这里解释一下其作用是 Received Line Signal Detector,即 接收线信号检出。当本地的 DCE(Data Communications Equipment,数据通信设备)收到由通信链路另一端的 DCE 送来的载波信号时,使 DCD 变为有效(高电平),表示已检测出远端的载波信号,要求数据终端设备(DTE)准备接收。DCD 信号通常来自串口连结线的另一端。这条信号线上的space电压表示另一端的电脑或者设备现在已经连接。但是,DCD 信号线却不是总可以得到的,有些设备上有这条信号线,而有的则没有。串口通信中一般有这条线。

使用示例如下:

fd = open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NONBLOCK);

mode 参数在第二个参数中有 O_CREAT 时才起作用,也就是说只有新建文件时才填写,用8进制的数(与umask有关)代表新建文件的权限。具体的使用方式我目前没涉及到,暂时先不记录了。

Linux中的 umask 函数主要用于在创建新文件或目录时 屏蔽掉新文件或目录不应有的访问允许权限,直接在 Linux 终端中输入 umask 即可查看本地 umask 权限值。在给文件赋权限时,我们使用 open 函数给的权限其实并不是文件真正的权限,还要与文件本地的掩码按位与之后的结果才是其真正的权限。通过 umask 可以获取本地的掩码或者修改本地的掩码。

贴个链接可以参考下:Linux之open()、close()函数_昒曦的博客-CSDN博客_close 头文件 

close() 函数参数说明

close 函数只有一个参数,即文件描述符,传入已打开文件的文件描述符即可关闭该文件。若关闭成功则返回 0,否则返回 -1 。

2、termios 结构体

termios 结构体中定义了设置串口有关的参数,tcsetattr() 函数用来根据 termios 结构体的设置来激活配置,其定义如下:

typedef unsigned char	cc_t;
typedef unsigned int	speed_t;
typedef unsigned int	tcflag_t;
#define NCCS 32

// termios 结构体 在头文件 termios-struct.h 里
struct termios{
    tcflag_t c_iflag;    // 输入模式标志。控制终端驱动程序从串口或键盘接收到的字符数据在被传递给应用程序之前的处理方式。
    tcflag_t c_oflag;    // 输出模式标志。控制由应用程序发送出去的字符数据在传递到串口或屏幕之前是如何处理的。
    tcflag_t c_cflag;    // 控制模式标志。对串口来说可以设置波特率,数据位、校验位、停止位的宽度、校验位等
    tcflag_t c_lflag;    // 本地模式用于控制终端的本地数据处理和工作模式。
    cc_t     c_line;     // 线路规程
    cc_t     c_cc[NCCS];  // 特殊控制字符。特殊控制字符是一些字符组合,如 Ctrl+C、 Ctrl+Z 等, 当用户键入这样的组合键,终端会采取特殊处理方式。
    speed_t  c_ispeed;   // 终端的输入速度
    speed_t  c_ospreed;  // 终端的输出速度
#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
};

// tcsetattr() 函数定义 定义在头文件 termios.h 中
tcsetattr(int fd, int optional_actions, const struct termios *termios_p)

a、c_cflag 控制模式标志位可选参数(unsigned short,16位)

c_cflag 参数可以用来设置波特率数据位校验位停止位的宽度、校验位等。在设置 c_cflag 参数时要用位操作来设置或清除相应的位,在源码中的有关宏定义如下:

// 波特率设置 以下定义在头文件 bits/termios.h 中
#define  B0	      0000000  // 挂起
#define  B50	  0000001
#define  B75	  0000002
#define  B110	  0000003
#define  B134	  0000004
#define  B150	  0000005
#define  B200	  0000006
#define  B300	  0000007
#define  B600	  0000010
#define  B1200	  0000011
#define  B1800	  0000012
#define  B2400	  0000013
#define  B4800	  0000014
#define  B9600	  0000015
#define  B19200	  0000016
#define  B38400	  0000017
// 波特率设置 以下定义在头文件 termios-baud.h 中
// 在 Linux 系统下, 使用 CBAUD 位掩码所选择的位来指定串口波特率
#define  CBAUD    0001017  // 波特率的位掩码 (not in POSIX)
#define  B57600   0010001
#define  B115200  0010002
#define  B230400  0010003
#define  B460800  0010004
#define  B500000  0010005
#define  B576000  0010006
#define  B921600  0010007
#define  B1000000 0010010
#define  B1152000 0010011
#define  B1500000 0010012
#define  B2000000 0010013
#define  B2500000 0010014
#define  B3000000 0010015
#define  B3500000 0010016
#define  B4000000 0010017
#define __MAX_BAUD B4000000
// 以下均定义在头文件 termios-c_cflag.h 中
// 停止位,设置该值则为2个停止位,不设置则为1个停止位
#define CSTOPB	0000100
// 数据位
#define   CS5	0000000  // 5 位数据位
#define   CS6	0000020  // 6 位数据位
#define   CS7	0000040  // 7 位数据位
#define   CS8	0000060  // 8 位数据位
// 设置该值则为2个停止位,不设置则为1个停止位
#define CSTOPB	0000100
// 使能校验位
#define PARENB	0000400
// 设置该值则使用奇校验,否则使用偶校验
#define PARODD	0001000
// 接收使能,这个位和下面那个位都是要在开始的时候使能的
#define CREAD	0000200
// 本地连接(不改变端口所有者),这个位和上面那个位都是要在开始的时候使能的
#define CLOCAL	0004000
// termios.c_cflag |=CLOCAL |CREAD;

b、c_iflag 输入模式标志位可选参数(unsigned short,16位)

// 以下定义在头文件 termios-c_iflag.h 中
#define IGNBRK 0000001 // 忽略输入终止条件
#define BRKINT 0000002 // 当检测到输入终止条件时发送SIGINT信号
#define IGNPAR 0000004 // 忽略奇偶校验错误
#define PARMRK 0000010 // 奇偶校验错误掩码
#define INPCK  0000020 // 奇偶校验使能
#define ISTRIP 0000040 // 裁剪掉第8比特,将所有接收到的数据裁剪为 7 比特位
#define INLCR  0000100 // 将接收到的 NL(换行)映射到 CR(回车)
#define IGNCR  0000200 // 忽略接收到的 CR
#define ICRNL  0000400 // 将接收到的 CR 映射到 NL
#define IUCLC  0001000 // 将接收到的大写字符映射到小写字符 (not in POSIX)
#define IXON   0002000 // 使能输出软件控制流
#define IXANY  0004000 // 输入任意字符可以重新启动输出
#define IXOFF  0010000 // 使能输入软件控制流
#define IMAXBEL 0020000 // 当输入队列满时响铃(ring bell)(not in POSIX)
#define IUTF8  0040000 // 输入是 UTF8 (not in POSIX)

c、c_oflag 输入模式标志位可选参数(unsigned short,16位)

// 以下定义在头文件 termios-c_oflag.h 中
#define OPOST  0000001 // 启动输出处理功能,如果不设置该位,将忽略下面介绍的所有设置
#define OLCUC  0000002 // 将输出中的大写字符转换成小写字符(not in POSIX)
#define ONLCR  0000004 // 将输出中的换行符(NL '\n')转换成回车符(CR '\r')
#define OCRNL  0000010 // 将输出中的回车符转换成换行符
#define ONOCR  0000020 // 如果当前列号为0,则不输出回车字符
#define ONLRET 0000040 // 不输出回车符
#define OFILL  0000100 // 发送填充字符以提供延时
#define OFDEL  0000200 // 如果设置该标志,则表示填充字符为 DEL 字符,否则为 NULL

#define NLDLY  0000400 // 换行符(newline)延时掩码
#define CRDLY  0003000 // 回车符(carriage-return)延时掩码
#define TABDLY 0014000 // 制表符(horizontal-tab)延时掩码
#define BSDLY  0020000 // 退格符(backspace)延时掩码
#define FFLDY  0100000 // 换页符(form-feed)延时掩码
#define VTDLY  0040000 // 垂直制表符(vertical-tab)延时掩码

d、c_lflag 本地模式标志位可选参数(unsigned short,16位)

// 以下定义在头文件 termios-c_lflag.h 中
#define ISIG   0000001  // 若收到信号字符(INTR,QUIT等)则会产生相应的信号
#define ICANON 0000002  // 启动规范(canonical)模式
#define ECHO   0000010  // 启动输入字符的本地回显功能
#define ECHOE  0000020  // 若设置ICANON,则允许退格操作
#define ECHOK   0000040 // 若设置ICANON,则KILL字符会删除当前行
#define ECHONL  0000100 // 若设置ICANON,则允许回显换行符
#define NOFLASH 0000200 // 在通常情况下,当接收到INTR,QUIT,SUSP控制字符时,会清空输入和输出队列。如果设置该标志,则所有的队列不会被清空
#define TOSTOP  0000400 // 若一个后台进程试图向它的控制终端进行写操作,则系统向该后台进程的进程组发送SIGTTOU信号。该信号通常终止进程的执行
#define ECHOCTL 0001000 // 若设置ECHO,则控制字符 Y(Y可以是回车符、制表符等)会显示成 "^X" 的样子,其中 "X" 的ASCII码等于给相应的控制字符的 ASCII 码加上 0x40。
                        // 例如,退格字符(0x08)会显示为“^H”('H'的 ASCII 码为 0x48)。这与我们在终端中按下 Ctrl+C 后会显示一个 "^C" 类似。
#define ECHOPRT 0002000 // 若设置ICANON和IECHO, 则删除字符和被删除的字符都会被显示
#define ECHOKE  0004000 // 若设置ICANON, 则允许回显在ECHOE和ECHOPRT中设定的KILL字符
#define IEXTEN  0100000 // 启动输入处理功能

注:规范模式非规范模式

ICANON 被用来设置规范模式。规范模式下,输入终端知道读到了行结束标志(回车符文件结束符 EOF(end of file))时输入缓冲区的数据才会被送到 read() 函数完成读取,也就是这种情况下的输入时基于行的操作。这与我们平时使用 cin 的时候的终端处理流程一样。

非规范模式下,所有的输入是即时有效的,不需要用户另外输入行结束符,而且不可进行行编辑。

下面的内容可以看到 c_cc 特殊控制字符中的 VTIME 与 VMIN 在非规范模式下的使用方式。

e、c_cc[NCC] 数组:特殊控制字符

c_cc 数组用于保存终端驱动程序中的特殊字符,如输入结束符等,可以理解为它是用来定义当输入为特殊字符(如ctrl+...的快捷键输入时)时程序应该做出哪些特殊的操作

#define VINTR  0 // (Ctrl-C) 中断控制字符。
                 // 该字符使终端驱动程序向与终端相连的进程以送SIGINT信号  
#define VQUIT  1 // (Ctrl-Z) 退出操作符。
                 // 该字符使终端驱动程序向与终端相连的进程发送SIGQUIT信号
#define VERASE 2 // (Backspace) 删除操作符。
                 // 该字符使终端驱动程序删除输入行中的最后一个字符,但不删除上一个EOF或行首。
                 // 当设置 ICANON 时可被识别,不再作为输入传递。  
#define VKILL  3 // (Ctrl-U) 删除行符。
                 // 删除输入行,即删除自上一个 EOF(文件结束符) 或行首以来的输入。
                 // 当设置 ICANON 时可被识别,不再作为输入传递。
#define VEOF   4 // (Ctrl-D) 文件结束符。
                 // 这个字符使得缓冲中的内容被送到等待输入的用户程序中,而不必等到 EOL。如果它
                 // 是一行的第一个字符,那么用户程序的 read() 将返回 0, 表示文件结束,即读到了EOF。 
                 // 当设置 ICANON 时可被识别,不再作为输入传递。
#define VTIME  5 // 在非规范模式下,指定读取的每个字符之间的超时时间,以十分之一秒为计时单位。
#define VMIN   6 // 在非规范模式下,指定最少读取的字符数。  
#define VSWTC  7 // 开关字符。(not in POSIX) 
#define VSTART 8 // (Ctrl-Q) 开启字符。重新开始被 STOP 字符中止的输出。
#define VSTOP  9 // (Ctrl-S) 停止字符。停止输出,直到键入 START 字符。 
#define VSUSP 10 // (Ctrl-Z) 挂起字符。向与终端相连的进程发送 SIGTSTP 信号,用于挂起当前的应用程序
#define VEOL  11 // 附加的行尾字符 EOL。对应键为 Carriage return(CR), 作用类似于行结束符。
                 // 当设置 ICANON 时可被识别。
#define VREPRINT 12 // (Ctrl-R) 重新输出未读的字符。
                    // 当设置 ICANON 和 IEXTEN 时可被识别,不再作为输入传递。  
#define VDISCARD 13 // (Ctrl-O) 开关:开始/结束丢弃未完成的输出。
                    // 当设置IEXTEN 时可被识别,不再作为输入传递。 
#define VWERASE  14 // (Ctrl-W) 删除词。
                    // 当设置 ICANON 和 IEXTEN 时可被识别,不再作为输入传递。  
#define VLNEXT   15 // (Ctrl-V) 字面上的下一个。引用下一个输入字符,取消它的任何特殊含义。
                    // 当设置IEXTEN 时可被识别,不再作为输入传递。  
#define VEOL2    16 // 第二行结束字符。,对应键为 Line feed(LF)。
                    // 当设置ICANON 时可被识别。  

VTIME和VMIN常规情况下,设置为0。但是有些应用场景我们需要使用非规范模式,也就是将二者结合起来共同控制对串口的读取行为,参数组合说明如下:

  • VMIN = 0 和 VTIME = 0 :在这种情况下,read 调用总是立刻返回。如果有等待处理的字符,read 就会立刻返回;如果没有字符等待处理,read 调用返回0,并且不读取任何字符;
  • VMIN = 0 和 VTIME > 0 :在这种情况下,只要有字符可以处理或者是经过 VTIME 个十分之一秒的时间间隔,read 调用就返回。如果因为超时而未读到任何字符,read 返回0,否则 read 返回读取的字符数目。
  • VMIN > 0 和 VTIME = 0 :在这种情况下,read 调用将一直等待,直到有 MIN 个字符可以读取时才返回,返回值是读取的字符数量。到达文件尾时返回0。
  • VMIN > 0 和 VTIME > 0 :在这种情况下, 当有 MIN 个字节可读或者两个输入字符之间的时间间隔超过 TIME 个十分之一秒时, read()函数才返回。因为在输入第一个字符后系统才会启动定时器,所以,在这种情况下, read()函数至少读取一个字节后才返回。

一个典型的串口初始化例子如下(这是我从最近看的一个云台设备的控制源码中截取的部分):

......
struct termios mytio;
// 波特率 38400, 8 位数据位, 使能接收并忽略调制解调器控制线
mytio.c_cflag = B38400 | CS8 | CLOCAL | CREAD; 
mytio.c_iflag     = IGNPAR;  // 忽略奇偶校验错误
mytio.c_oflag     = 0;  // 不启用输出控制
mytio.c_cc[VTIME] = 0;  // 规范模式
mytio.c_cc[VMIN]  = 0;  // 规范模式

tcflush(fd, TCIFLUSH);  // 清空输入缓冲区
tcsetattr(fd, TCSANOW, &mytio);  // 初始化串口
......

3、tcsetattr() / tcgetatt()函数

tcsetattr() 函数可以设置串口的结构属性,tcgetatt() 可以获取串口的结构属性。

tcsetattr() 函数用来根据 termios 结构体的设置来激活配置。声明如下:

// tcsetattr() 函数定义
tcsetattr(int fd, int optional_actions, const struct termios *termios_p)

tcsetattr() 函数的第一个参数是是文件描述符,第三个参数 termios 是结构体指针。第二个参数 optional_actions 指定了什么时候改变会起作用,可选值如下:

// 源码中都是宏定义的形式
// 配置的修改立即生效
#define	TCSANOW		0  
// 改变在所有写入 fd 的输出都被传输后生效。这个函数应当用于修改影响输出的参数时使用。(当前输出完成时将值改变) 
#define	TCSADRAIN	1 
// 改变在所有写入 fd 引用的对象的输出都被传输后生效,所有已接受但未读入的输入都在改变发生前丢弃(同TCSADRAIN,但会舍弃当前所有值)。 
#define	TCSAFLUSH	2  

可以通过  tcgetattr() 函数获取 termios  结构体属性

// 函数声明,获取成功返回 0,否则返回 -1
int tcgetattr(int fd, struct termios *termios_p)
/*
使用方法举例
*/
struct termios getitem;
if(tcgetattr(fd, &getitem) == -1)
{
    cout << "failed" << endl;
}

4、tcflush() 函数

不过在调用 tcsetattr() 之前最好调用 tcflush() 函数选择性地清空 I/O 缓冲区(输入、输出或者两者都清空)中的数据,其声明如下:

int tcflush(int fd, int queue_selector)

参数 queue_selector 可以选择的值如下:

// 定义在头文件 bits/termios.h 中
#define TCIFLUSH 0   // 清空输入缓冲区
#define TCOFLUSH 1   // 清空输出缓冲区
#define TCIOFLUSH 2  // 清空输入和输出缓冲区
// 使用举例,清空输入缓冲区
tcflush(fd, TCIFLUSH)

5、write()/read() 函数

调用 write()/read() 函数(需包含头文件 unistd.h)事项串口数据的读写,在头文件 unistd.h 中,其原型如下

// 返回值是读/写的数据的数量,如果发生错误则返回 -1,如果读/写到 EOF 则返回 0。
ssize_t read(int fd, void* buf, size_t nbytes)
ssize_t write(int fd, const void* buf, size_t nbytes)

很容易理解,第一个参数 fd 是要操作的文件/设备的文件描述符,第二个参数 *buf 是要读写的数据的地址,第三个参数 nbytes 是要读写的数据字节数。如果在 read() 函数中被请求读取的数据字节数小于当前行可读取的字节数,则 read() 函数只会读取被请求的字节数,剩下的字节下次再被读取。

6、ioctl() 函数

可以调用 ioctl() 函数对设备的 IO 通道进行管理, ioctl() 函数的声明如下:

// 包含头文件 unistd.h ,第三个参数总是一个指针,但指针的类型依赖于request参数。
int ioctl(int fd, unsigned long int request, void *arg )

该函数的说明较为复杂,这里不展开讲解,有兴趣可以查看相关资料,或者文末的链接。

一个使用 ioctl() 获取缓冲区的字节数的例子:

// 获取接收缓存区中的字节数并赋值给第三个参数,此时第三个参数是整型指针
int bytes_available;
ioctl(fd, FIONREAD, &bytes_available)

7、其他函数tcdrain() / tcflow()

tcdrain() 函数的作用是阻塞程序,直到发送缓冲区的数据发送完毕,函数定义如下:

// 调用成功时返回 0;失败将返回-1,并设置 errno
int tcflush(int fd);

tcflow() 函数的作用是暂停或重新开启 fd 的传输,具体与 action 的设置有关,函数定义如下:

// 调用成功时返回 0;失败将返回-1,并设置 errno
int tcflow(int fd, int action);

action 可选的四个参数如下:

#define TCOOFF 0 // 暂停数据输出(输出传输)
#define TCOON  1 // 重新启动暂停的输出
#define TCIOFF 2 // 发送 STOP 字符,停止终端设备向系统发送数据
#define TCION  3 // 发送一个 START 字符,启动终端设备向系统发送数据;

参考:

linux应用编程12-串口终端_邻居家的小南瓜的博客-CSDN博客_linux串口应用

Linux ~ termios 串口编程 - Burden - 博客园

Linux串口应用编程详解(Serial)_Mculover666的博客-CSDN博客_linux 串口编程

linux termios结构_querdaizhi的博客-CSDN博客_linux termios

tcgetattr: 

tcgetattr函数的说明_petershina的博客-CSDN博客_tcgetattr函数

ioctl:

Linux内核驱动 --ioctl函数解析_一只特立独行的程序猿的博客-CSDN博客_linux驱动ioctl

ioctl( ) 函数 - 拦云 - 博客园 (cnblogs.com)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux 串口编程学习记录(termios.h) 的相关文章

  • 标准头文件中的 C 编译器错误 - 未定义的 C++ 定义

    我正在尝试编译 C 程序 但收到许多错误 这些错误是在标准 C 头文件 inttypes h stdio h stat h 等 中遇到的 错误的来源是以下未定义的常量 BEGIN DECLS END DECLS BEGIN NAMESPAC
  • 如何以编程方式从Linux中的进程名称获取进程ID

    在我的项目中 我们使用 ACE 自适应通信环境 中间件来编写可在 Windows 和 Linux 上运行的独立于操作系统的代码 要求是从进程名称中获取进程 ID 由于 ACE 不支持这一点 因此我们必须使用特定于平台的宏来分离 Window
  • 每个进程每个线程的时间量

    我有一个关于 Windows 和 Linux 中进程和线程的时间量子的问题 我知道操作系统通常为每个线程提供固定的时间量 我知道时间量根据前台或后台线程而变化 也可能根据进程的优先级而变化 每个进程有固定的时间量吗 例如 如果操作系统为每个
  • Linux shell 脚本:十六进制数字到二进制字符串

    我正在 shell 脚本中寻找一些简单的方法来将十六进制数字转换为 0 和 1 字符的序列 Example 5F gt 01011111 是否有任何命令或简单的方法来完成它 或者我应该为其编写一些开关 echo ibase 16 obase
  • linux x86 汇编语言 sys_read 调用的第一个参数应为 0 (stdin)

    我正在编写一个简单的汇编程序来从标准输入读取 如 scanf 这是我的代码 section bss num resb 5 section txt global start start mov eax 3 sys read mov ebx 0
  • 如何在特定 systemd 服务重新启动时触发自定义脚本运行

    我想知道如何安排自定义脚本在重新启动服务时运行 我的用例是 每当重新启动 Tomcat 服务时 我都必须运行多个命令 我想知道是否有一种方法可以编写脚本并安排它在重新启动 Tomcat 服务时运行 我已将 tomcat 脚本设置为 syst
  • 如何查找连接到 AF_INET 套接字的客户端的 UID?

    有什么方法或类似的东西ucred for AF UNIX如果是AF INET插座 TCP在我的例子中 找出连接到我的套接字的客户端的UID 还有 proc net tcp但它显示了UID of the creator插座的而不是连接的cli
  • Linux shell 脚本中的 while 循环超时

    这工作正常 无限循环 while TRUE do printf done 我在尝试着timeout this while loop与timeout命令 所有这些都不起作用 timeout 5 while TRUE do printf don
  • 信号处理程序有单独的堆栈吗?

    信号处理程序是否有单独的堆栈 就像每个线程都有单独的堆栈一样 这是在 Linux C 环境中 来自 Linux 手册页signal 7 http kernel org doc man pages online pages man7 sign
  • PHP 致命错误:未找到“MongoClient”类

    我有一个使用 Apache 的网站 代码如下 当我尝试访问它时 我在 error log 中收到错误 PHP Fatal Error Class MongoClient not found 以下是可能错误的设置 但我认为没有错误 php i
  • 在Linux上编译C# + WPF以便在Windows上运行

    我有一个 C 应用程序 其中某些部分是使用 WPF 编写的 Mono 不支持 可以在 Linux 上编译这个应用程序吗 最终 该应用程序将在 Windows 上运行 但它是更大框架的一部分 并且我们的整个构建过程在 Linux 上运行 因此
  • xsel -o 对于 OS X 等效项

    是否有一个等效的解决方案可以在 OS X 中抓取选定的文本 就像适用于 Linux 的 xsel o 一样 只需要当前的选择 这样我就可以在 shell 脚本中使用文本 干杯 埃里克 你也许可以安装xsel在 MacOS 上 更新 根据 A
  • 拆分字符串以仅获取前 5 个字符

    我想去那个地点 var log src ap kernelmodule 10 001 100 但看起来我的代码必须处理 ap kernelmodule 10 002 100 ap kernelmodule 10 003 101 等 我想使用
  • 从 PL/SQL 调用 shell 脚本,但 shell 以 grid 用户而非 oracle 身份执行

    我正在尝试使用 Runtime getRuntime exec 从 Oracle 数据库内部执行 shell 脚本 在 Red Hat 5 5 上运行的 Oracle 11 2 0 4 EE CREATE OR REPLACE proced
  • 强制卸载 NFS 安装目录 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案
  • 如何检测并找出程序是否陷入死锁?

    这是一道面试题 如何检测并确定程序是否陷入死锁 是否有一些工具可用于在 Linux Unix 系统上执行此操作 我的想法 如果程序没有任何进展并且其状态为运行 则为死锁 但是 其他原因也可能导致此问题 开源工具有valgrind halgr
  • 如何在 Linux 中编写文本模式 GUI? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 当我编写脚本 程序时 我经常想弹出一个简单的文本 gui 来提示输入 我该怎么做 例如 来自 Shel
  • nginx 上的多个网站和可用网站

    通过 nginx 的基本安装 您的sites available文件夹只有一个文件 default 怎么样sites available文件夹的工作原理以及如何使用它来托管多个 单独的 网站 只是为了添加另一种方法 您可以为您托管的每个虚拟
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach
  • 如何在bash中使用jq从变量中包含的json中提取值

    我正在编写一个 bash 脚本 其中存储了一个 json 值 现在我想使用 Jq 提取该 json 中的值 使用的代码是 json val code lyz1To6ZTWClDHSiaeXyxg redirect to http examp

随机推荐

  • 一个体验超级好的chatgpt国产镜像

    镜像网址 xff1a https chatgpt 6om net 1 xff0c 首页的ui xff0c 基本与chatgpt官方一致 2 xff0c 聊天窗 xff0c 反馈很好 3 xff0c 写代码 xff0c 体验也很棒哟
  • ChatGPT国内初次体验:聊天、Python代码生成等

    ChatGPT国内镜像站初体验 xff0c 聊天 Python代码生成 ChatGPT官网 xff1a https ai com ChatGPT 最近ChatGPT传得沸沸扬扬 xff0c 红得发紫 由于主站在国外 xff0c 我没有资源和
  • 马云回国,首谈ChatGPT

    马云今天回国了 xff0c 这是一个备受关注的消息 作为中国最具代表性的企业家之一 xff0c 马云在过去的二十多年里 xff0c 带领阿里巴巴从一个小小的创业公司 xff0c 发展成为全球最大的电商平台之一 xff0c 同时也推动了中国互
  • 下一代的新操作系统就是ChatGPT!

    什么是CHatgpt xff1f ChatGPT是人工智能研究实验室OpenAI在2022年11月30日推出的聊天机器人模型 xff0c 它使用Transformer神经网络架构 xff0c 训练数据来自包括维基百科 xff0c 以及真实对
  • ChatGPT云桌面:无需科技挂载,即点即用

    ChatGPT是一个由OpenAI开发的人工智能对话语言模型 它被设计为对话式人工智能代理 xff0c 用于客户服务 个人助理和文娱等任务 它可以理解并生成多种语言的文本 xff0c 包括中文 英语 西班牙语 德语等 但从某些地方访问Cha
  • 不写代码、靠“玩” ChatGPT 年入百万,提示工程师正变成硅谷新宠

    以下文章转发自来源于硅星人 xff0c 作者章姝敏 随着 ChatGPT 等 AI 工具的风靡 xff0c 越来越多人将其作为日常生活和工作的助手 为了能更好地与它对话 xff0c 一个新兴职业 提示工程师应运而生 用自然语言对话 xff0
  • 有个周入百万的项目:教人用ChatGPT。

    第一批靠 ChatGPT 赚大钱的人 xff0c 既不是研发人员 xff0c 也不是国内大厂 xff0c 又是这群卖课的 xff1f 不知道大家有没有刷到过下面这张图 xff0c 有人统计了知识星球上 xff0c 这段时间跟 GPT 相关课
  • 用ChatGPT搭建公司内部ChatGPT服务器

    一 前言 我是ChatGPT xff0c 一个由OpenAI训练的大型语言模型 我被设计用于回答各种问题并生成文本 xff0c 可以处理多种自然语言任务 xff0c 例如问答 摘要和翻译等 在我的学习过程中 xff0c 我阅读了数百万篇文本
  • 通过串口波特率计算数据传输速率(每秒字节数)

    这个是个古老的问题 上次用串口还是本科时候 xff0c 最近面试被问到了这个问题竟然整蒙了 xff0c 大致是 xff1a 面试老师问 xff1a 9600的波特率每秒可以传输多少个字节 xff1f 我 xff1a e 直接除以8 emmm
  • ChatGPT搭建AI网站实战

    1 概述 ChatGPT是一款基于GPT 3 5架构的大型语言模型 xff0c 它能够进行自然语言处理和生成对话等任务 作为一款智能化的聊天机器人 xff0c ChatGPT有着广泛的应用场景 xff0c 如在线客服 智能助手 个性化推荐等
  • Midjourney关键词分享!附输出AI绘画参考图

    Midjourney 关键词是指用于 Midjourney 这个 AI 绘画工具的文本提示 xff0c 可以影响生成图像的风格 内容 细节等 Midjourney 关键词有一些基本的语法规则和套用公式 xff0c 也有一些常用的风格词汇和描
  • 【AI绘画】——Midjourney关键词格式解析(常用参数分享)

    目前在AI绘画模型中 xff0c Midjourney的效果是公认的top级别 xff0c 但同时也是相对较难使用的 xff0c 对小白来说比较难上手 xff0c 主要就在于Mj没有webui xff0c 不能选择参数 xff0c 怎么找到
  • ChatGPT总是答非所问?如何使用chatgpt定义角色

    一 x1f4dd 定义角色 xff1a ChatGPT 的角色设定 背景信息 xff1a 提供详细 准确的背景信息和前提条件 xff0c 以便 ChatGPT 提供有针对性的回答和建议 任务目标 xff1a 清晰地描述希望 ChatGPT
  • 免费ChatGPT接入-国内怎么玩chatGPT

    免费ChatGPT中文版 OpenAI 的 GPT 模型目前并不提供中文版的免费使用 xff0c 但是有许多机器学习平台和第三方服务提供商也提供了基于 GPT 技术的中文版模型和 API 下面是一些常见的免费中文版 ChatGPT xff1
  • 分享一个国内可用的免费GPT-AI网站

    背景 ChatGPT作为一种基于人工智能技术的自然语言处理工具 xff0c 近期的热度直接沸腾 x1f30b 我们也忍不住做了一个基于ChatGPT的网站 xff0c 可以免登陆 xff01 xff01 国内可直接对话AI xff0c 也有
  • ChatGPT狂飙之下 云计算加速键启动?

    集微网消息 xff0c ChatGPT一夜爆火 xff0c 成为AI届的 流量收割机 有观点认为 xff0c ChatGPT不仅是AI的成功 xff0c 也是云计算的成功 AIGC xff08 人工智能生成内容 xff09 有望开启云计算产
  • ChatGPT :国内免费可用 ChatGPT +Midjourney绘图

    前言 ChatGPT xff08 全名 xff1a Chat Generative Pre trained Transformer xff09 xff0c 美国OpenAI 研发的聊天机器人程序 xff0c 于2022年11月30日发布 C
  • 分享一个国内免费的ChatGPT镜像网址(亲测有效-5月7日更新)

    最近由于ChatGPT的爆火也让很多小伙伴想去感受一下ChatGPT的魅力 xff0c 那么今天就分享几个ChatGPT国内的镜像网址 xff0c 大家可以直接使用 xff01 记得点赞收藏一下呦 xff01 1 Mental AI 地址
  • Chat GPT国内懒人专用版(基于网站开发使用)

    一 xff1a 概述 小伙伴们肯定都知道沸沸扬扬的Chat GPT xff08 全名 xff1a Chat Generative Pre trained Transformer xff09 xff0c 美国Open AI研发的聊天机器人程序
  • Linux 串口编程学习记录(termios.h)

    目录 0 Linux 串口编程简述 1 open close 函数 open 函数参数说明 xff1a close 函数参数说明 2 termios 结构体 a c cflag 控制模式标志位可选参数 xff08 unsigned shor