Linux 串口编程
目录
- 前言
- 一、tty体系
- 二、串口硬件基础知识
- 三、Linux下的串口编程
- 3.1 打开串口
- 3.2 从串口读写数据,问题1、2的诞生
- 3.3 关闭串口
- 3.4 串口配置
- 3.4.1 获取/设置串口的参数
- 3.4.2 设置波特率
- 3.4.3 设置控制模式标志
- 3.4.4 设置本地模式标志
- 3.4.5 设置输入模式标志
- 3.4.6 设置输出模式标志
- 3.4.7 设置控制字符
- 3.4.8 清空发送/接收缓冲区
- 四、解决问题 1、2
- 4.1 cfmakeraw() RAW模式
- 4.2 改进串口数据读取
- 五、完整的示例代码
- 六、参考链接:
前言
在嵌入式Linux中,串口是一个字设备,访问具体的串行端口的编程与读/写文件的操作类似,只需打开相应的设备文件即可操作。串口编程特殊在于串口通信时相关参数与属性的设置。嵌入式Linux的串口编程时应注意,若在根文件中没有串口设备文件,应使用mknod命令创建,这这里假设串口设备是/dev/ttyS0,介绍一下串口的编程过程。
#mknod /dev/ttyS0 c 4 64
一、tty体系
tty是teletype的缩写,在上世纪计算机还很昂贵的时候,多人可以通过这种终端来连接并共用一台计算机,发展到今日,tty已经成为了字符类设备的统称,这类设备包括:控制台、UART等物理串行接口以及伪终端。也就是说,开发板物理串口一般对应linux中/dev目录下的tty*设备文件,访问这些文件,就访问硬件串口了。
二、串口硬件基础知识
串口是一类以串行方式传输数据的接口(每次1bit)这类接口常用于网络设备、键盘、鼠标、调制解调器、以及终端设备(teletype,上世纪电脑还是大块头时,大家通过这种设备远程共用一台电脑)等。
常用bps(每秒传输的位数)或称为波特率来表示串口的通讯速度,常见的有9600bps、38400bps、115200bps等。
对于常用的RS232接口,除了常见的TXD、RXD、GND这三个必须的通讯信号线外,还有一些用于控制的信号线:
名称 | 方向 | 用途 |
---|---|---|
DCD(Data Carrier Detect) | 输入 | 如果读到低电平(逻辑1),说明线缆对面的设备已经正确连接。 |
DTR(Data Terminal Ready) | 输出 | 输出低电平(逻辑1)表明我方已经准备好数据传输,一般软件打开串行端口时,此信号会自动拉低。 |
CTS(Clear To Send) | 输入 | 如果读到低电平(逻辑1),说明线缆对面的设备允许我们此时发送数据。 |
RTS(Request To Send) | 输出 | 输出低电平(逻辑1)以请求线缆对面的设备传输数据,大多数时候,此信号线总是输出低电平。 |
一般在连接时,我方的DTR连接对方的DCD,我方的RTS连接对方的CTS,反之亦然。**DCD和DTR信号用于设备检测,CTS和RTS信号用于进行信号流控制(除此之外还有一种软件信号流控制方法,当然我在工作中很少用到这些)。
三、Linux下的串口编程
既然Linux下串口设备是以文件的形式存在,我们当然可以用通用的文件I/O函数访问它们,不过访问设备文件一般需要超级管理员权限,在开发板上我们一般以root身份登录系统,这当然也就不存在问题。除此之外,为了对串口进行设置,Linux系统提供了一个名为 termios.h 的文件,里面包含串口设置相关的数据结构以及函数接口,这些函数接口,归根结底其实也是调用了文件I/O函数中的ioctl函数。
下面的示例代码中,均默认包含以下头文件:
#include <stdio.h>
#include <string.h>
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
3.1 打开串口
以下代码演示如何正确打开一个串口设备文件
打开串口设备文件的操作与普通文件的操作类似,都采用标准的I/O操作函数open()。
fd = open("/dev/ttyS0",O_RDWR|O_NDELAY|O_NOCTTY);
open()函数有两个参数,第一个参数是要打开的文件名(此处为串口设备文件/dev/ttyS0);第二个参数设置打开的方式,O_RDWR表示打开的文件可读/写,O_NDELAY表示以非阻塞方式打开,O_NOCTTY表示若打开的文件为终端设备,则不会将终端作为进程控制终端。
3.2 从串口读写数据,问题1、2的诞生
串口的数据读/写与普通文件的读/写一样,都是使用read()/write()函数实现。
n = write( fd, buf, len ); //将buf中len个字节的数据从串口输出,返回输出的字节数
n = read( fd, buf, len ); //从串口读入len个字节的数据并放入buf, 返回读取的字节数
示例如下:
写数据
/** write data to serial port* return the length of bytes actually written on success, or -1 on error*/
ssize_t write_port(int fd, void *buf,size_t len)
{ssize_t actual_write;actual_write = write(fd, buf, len);if (actual_write == -1){/* write failure */perror("write_port: Unable to write port - ");}return actual_write;
}
读数据
/** read data from serial port* return the length of bytes actually read on success, or -1 on error*/
ssize_t read_port(int fd, void *buf, size_t len)
{ssize_t actual_read;actual_read = read(fd, buf, len);if (actual_read == -1){/* read failure */perror("read_port: Unable to read port - ");}return actual_read;
}
函数实现了读取功能,但是存在两个问题:
1.只有在读完一行才会退出,也就是读到’\r’或’\n’,否则进程会一直堵塞到read函数上;
2.如果串口没有收到数据,函数会一直堵塞直到超时或接收到数据,最小接收长度以及超时时间可以通过后面提到的配置函数进行配置;
问题1可以通过设置串口终端工作在RAW模式解决,问题2可以通过设置串口的最小接收字节数和超时时间解决,具体见 3.4 小节的串口配置内容。
3.3 关闭串口
关闭串口的操作很简单,将打开的串口设备文件句柄关闭即可。
close(fd);
3.4 串口配置
Linux提供了一组用于配置串口终端的数据结构以及对应的函数接口,称为 “POSIX termios interface”。要使用它们,只需要包含此头文件:
#include <termios.h> /* POSIX terminal control definitions */
它的参数设置需要使用struct termios结构体,这个结构体在termio.h文件中定义,且应在程序中包含这个头文件。
typedef unsigned char cc_t ;
typedef unsigned int speed_t ;
typedef unsigned int tcflag_t ;
struct termios{tcflag_t c_iflag ; /*输入模式标志*/tcflag_t c_oflag ; /*输出模式标志*/tcflag_t c_cflag ; /*控制模式标志*/tcflag_t c_lflag ; /*本地模式标志*/tcflag_t c_line ; /*行规程类型,一般应用程序不使用*/cc_t c_cc[NCC]; /*控制字符*/speed_t c_ispeed ; /*输入数据波特率*/speed_t c_ospeed ; /*输出数据波特率*/};
串口的设置主要是设置这个结构体的各成员值,然后利用该结构体将参数传给硬件驱动程序。在Linux中,串口以串行终端的方式进行处理,因而,可以使用tcgetattr()/tcsetattr()函数获取/设置串口的参数。
3.4.1 获取/设置串口的参数
通过系统提供的如下两个接口,我们可以获取当前串口的状态或设置新的状态:
int tcgetattr(int fd, struct termios *termios_p);
int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);
这两个参数都有一个批向termios结构体的指针作为参数,用于返回当前终端的属性或设置该终端的属性。参数fd就是用open()函数打开的终端文件句柄,而串口就是用open()打开的串口设备文件句柄。tcsetattr()函数的optional_action参数用于指定新设定的参数起作用的时间,其设定值可以为:
- TCSANOW 改变立即生效
- TCSADRAIN 在所有的输出都被传输后改变生效,适用于更改影响输出参数的情况。
- TCSAFLUSH 在所有输出都被传输后改变生效,丢弃所有末读入的输入(清空输入缓 存)。
3.4.2 设置波特率
使用cfsetospeed()/cfsetispeed()函数设置波特率,它们分别用于在termios结构体中设置输出和输入的波特率。设置波特率可以使用波特率常数,其定义为字母“B+速率”,如B19200就是波特率为19200bps,B115200就是波特率为115200bps。
int cfsetispeed( struct termios *termios_p, speed_t speed ); //speed为波特率常数
int cfsetospeed( struct termios *termios_p, speed_t speed );
例 :
cfsetispeed( ttys0_opt, B115200 );
cfsetospeed( ttys0_opt, B115200 );
3.4.3 设置控制模式标志
控制模式标志c_cflag主要用于设置串口对DCD信号状态检测、硬件流控制、字符位宽、停止位和奇偶校验等,常用标志位如下:
CLOCAL 忽略DCD信号,若不使用MODEM,或没有串口没有CD脚就设置此标志
CREAD 启用接收装置,可以接收字符
CRTSCTS 启用硬件流控制,对于许多三线制的串不应使用,需设置~CRTCTS
CSIZE 字符位数掩码,常用CS8
CSTOPB 使用两个停止位,若用一位应设置~CSTOPB
PARENB 启用奇偶校验
例如,下面的代码将串口设置为忽略DCD信号,启用接收装置,关闭硬件流控制,传输数据时使用8位数据位和一位停止位(8N1),不使用奇偶校验。
struct temios ttys0ttyso_opt.c_cflag |= CLOCAL | CREAD ; //将CLOCAL与CREAD位设置为1ttys0_opt.c_cflag &= ~CRTSCTS ; //将硬件流控制位CRTSCTS清0,其他位不变ttys0_opt.c_cflag &= ~CSIZE ; //清除数据位掩码ttys0_opt.c_cflag |= CS8 ; //设置8位数据位标志CS8ttys0_opt.c_cflag &= ~(PARENB|CSTOPB); //使用1位停止位,停用奇偶校验
3.4.4 设置本地模式标志
本地模式标志c_lflag主要用于设置终端与用户的交互方式,常见的设置标志位有ICAN-ON,ECHO和ECHOE等。其中,ICANON标志位用于实现规范输入,即read()读到行结束符后返回,常用于终端的处理;若串口用于发送/接收数据,则应清除此标志,使用非规范模式(raw mode)。非规范模式中,输入数据不组成行,不处规范模式中的特殊字符。在规范模式中,当设置ECHO标志位时,用户向终端输入的字符将被回传给用户;当设置ECHOE标志位时,用户输入退格键时,则回传“退格-空格-退格”序列给用户,使得退格键覆盖的字符从显示中消失,这样更符合用户的习惯(若未设置此标志,输入退格键时,则光标回退一个字符,但原有的字符未从显示中消失)。
3.4.5 设置输入模式标志
输入模式标志c_iflag主要用于控制串口的输入特性,常用的设置有IXOFF和IXON,分别用于软件流控制。其中,IXOFF用于防止输入缓冲区溢出;IXON则是在输入数据中识别软件流控制标志。由于许多嵌入式系统无法使用硬件流控制,因此,只能使用软件流控制数据传输的速度,但是,它可能降低串口数据传输效率。启用软件流控制的代码如下:
ttys0_opt.c_iflag |= IXOFF|IXON ;
3.4.6 设置输出模式标志
输出模式标志c_oflag主要用于对串口在规范模式时输出的特殊字符处理,而对非规范模式无效。
3.4.7 设置控制字符
在非规范模式中,控制字符数组c_cc[]中的变量c_cc[VMIN]和c_cc[VTIME]用于设置read()返回前读到的最少字节数和读超时时间,其值分为四种情况:
- 1.c_cc[VMIN]>0,c_cc[VTIME]>0
读到一个字节后,启动定时器,其超时时间为c_cc[VTIME],read()返回的条件为至少读到c_cc[VMIN]个字符或定时器超期。 - 2.c_cc[VMIN]>0, c_cc[VTIME] ==0
只要读到数据的字节数大于等于c_cc[VMIN],则read()返回;否则,将无限期阻塞等待。 - 3.c_cc[VMIN] == 0, c_cc[VTIME]>0
只要读到数据,则read()返回;若定时器超期(定时时间c_cc[VTIME])却未读到数据,则read()返回0; - 4.c_cc[VMIN] == 0, c_cc[VTIME] == 0
若有数据,则read()读取指定数量的数据后返回;若没有数据,则read()返回0;
在termios结构体中填写完这些参数后,接下来就可以使用tcsetattr()函数设置串口的属性。
tcsetattr( fd, &old_opt ); //将原有的设置保存到old_opt,以便程序结束后恢复
tcsetattr( fd, TCSANOW, &ttsy0_opt );
3.4.8 清空发送/接收缓冲区
为保证读/写操作不被串口缓冲区中原有的数据干拢,可以在读/写数据前用tcflush()函数清空串口发送/接收缓冲区。tcflush()函数的参数可为:
TCIFLUSH 清空输入队列
TCOFLUSH 清空输出队列
TCIOFLUSH 同时清空输入和输出队列
四、解决问题 1、2
4.1 cfmakeraw() RAW模式
示例为一个串口配置函数,其将串口配置为传入的波特率,8位数据位,无校验位,RAW格式:
/** config serial port baud * and set data format to 8N1(8bits data, no parity bit, 1 stop bit)* return 0 on success, or -1 on error*/
int config_port(int fd, speed_t baud)
{struct termios term;/* read serial port configure */if (tcgetattr(fd, &term) != 0){perror("config_port: Unable to read configure - ");return -1;}/* set baudrate */cfsetspeed(&term, baud);/* 8N1 mode */term.c_cflag &= ~PARENB;term.c_cflag &= ~CSTOPB;term.c_cflag &= ~CSIZE;term.c_cflag |= CS8;/* enbale raw mode */cfmakeraw(&term);/* write serial port configure */if (tcsetattr(fd, TCSADRAIN, &term) != 0){perror("config_port: Unable to write configure - ");return -1;}
}
cfmakeraw()
函数使得串口工作于RAW模式,在此模式下,tty子系统会将从串口收到的所有字节数据直接递交给应用层,而不进行额外处理,此时read()函数会在读取完缓冲区的所有数据后立刻退出并返回实际读到的数值,而不是等到\r或\n的到来,这便解决了上面读取函数的问题1。
4.2 改进串口数据读取
可以在开启串口的RAW模式后,通过配置termios结构体中的成员:
.c_cc[VTIME]; /* 指定超时时间 */
.c_cc[VMIN]; /* 指定最少读取的字节 */
来指定read读取时至少需要读到多少字节才返回(这个需要配合串口的RAW格式),也可以对接收的超时时间进行设置,如果将这 两者都设为0
,则不管是否读到数据,read函数都会立刻退出,这就解决了前面提到的问题2。
五、完整的示例代码
仅供参考
#include <errno.h> /* Error number definitions */
#include <fcntl.h> /* File control definitions */
#include <stdio.h>
#include <string.h>
#include <termios.h> /* POSIX terminal control definitions */
#include <unistd.h> /* UNIX standard function definitions *//** open serial port* return file descriptor on success or -1 on error.*/
int open_port(char *path)
{int fd;fd = open(path, O_RDWR | O_NOCTTY | O_NDELAY);if (fd == -1){/* open failure, print system error msg. */perror("open_port: Unable to open port - ");}else{/* clear file descriptor flags */fcntl(fd, F_SETFL, 0);return fd;}
}/** write data to serial port* return the length of bytes actually written on success, or -1 on error*/
ssize_t write_port(int fd, void *buf, size_t len)
{ssize_t actual_write;actual_write = write(fd, buf, len);if (actual_write == -1){/* write failure */perror("write_port: Unable to write port - ");}return actual_write;
}/* set timeout and minimum number of bytes to read */
int read_port_setup(int fd, cc_t timeout_sec, cc_t min_bytes)
{struct termios term;/* read serial port configure */if (tcgetattr(fd, &term) != 0){perror("config_port: Unable to read configure - ");return -1;}/* set timeout in deciseconds for noncanonical read */term.c_cc[VTIME] = timeout_sec * 10;/* set minimum number of bytes to read */term.c_cc[VMIN] = min_bytes;/* write serial port configure */if (tcsetattr(fd, TCSADRAIN, &term) != 0){perror("config_port: Unable to write configure - ");return -1;}
}/** read data from serial port* return the length of bytes actually read on success, or -1 on error** fd - file descriptor* buf - pointer of buffer to receive bytes* len - buffer* sec - timeout second* min - minimum bytes to read*/
ssize_t read_port(int fd, void *buf, size_t len, cc_t sec, cc_t min)
{ssize_t actual_read;/* setup serial port */if (read_port_setup(fd, sec, min) == -1){return -1;}/* read bytes from serial port */actual_read = read(fd, buf, len);if (actual_read == -1){/* read failure */perror("read_port: Unable to read port - ");}return actual_read;
}/** config serial port baud and set data format to 8N1* (8bits data, no parity bit, 1 stop bit)* return 0 on success, or -1 on error*/
int config_port(int fd, speed_t baud)
{struct termios term;/* read serial port configure */if (tcgetattr(fd, &term) != 0){perror("config_port: Unable to read configure - ");return -1;}/* set baudrate */cfsetspeed(&term, baud);/* 8N1 mode */term.c_cflag &= ~PARENB;term.c_cflag &= ~CSTOPB;term.c_cflag &= ~CSIZE;term.c_cflag |= CS8;/* enbale raw mode */cfmakeraw(&term);/* write serial port configure */if (tcsetattr(fd, TCSADRAIN, &term) != 0){perror("config_port: Unable to write configure - ");return -1;}
}/** close serial port */
int close_port(int fd)
{if (close(fd) == -1){perror("close_port: Unable to close port - ");return -1;}return 0;
}int main(int argc, char *argv[])
{char *path = "/dev/ttyS0";int fd;char send_string[] = "hello world!\n";char read_string[20] = "";ssize_t length;/* open port */fd = open_port(path);if (fd > 0){printf("open %s success, fd = %d.\n", path, fd);}/* config port */config_port(fd, B9600);/* write data to port */length = write_port(fd, send_string, sizeof(send_string));if (length >= 0){printf("%ld bytes written.\n", length);}/* read data from port */length = read_port(fd, read_string, 20, 5, 5);if (length >= 0){printf("%ld bytes read : ", length);for (ssize_t i = 0; i < length; i++){printf("%02X ", (int)(read_string[i]));}printf("\n");}/* close port */close_port(fd);return 0;
}
六、参考链接:
linux 串口编程
嵌入式linux入门3-2-串口
相关文章:
Linux 串口编程
目录 前言一、tty体系二、串口硬件基础知识三、Linux下的串口编程3.1 打开串口3.2 从串口读写数据,问题1、2的诞生3.3 关闭串口3.4 串口配置3.4.1 获取/设置串口的参数3.4.2 设置波特率3.4.3 设置控制模式标志3.4.4 设置本地模式标志3.4.5 设置输入模式标志3.4.6 设置输出模式标…...
Adminer源码编译 精简语言中英文和基本使用方法
Adminer是一个小而强悍的基于web的数据库管理工具, 官方默认支持几十种语言,但是对于中国的用户而言只需要有中文和英文就够了,其他语言基本无用。这就需要我们下载Adminer源码自己编译 Adminer.php , 如下图所示 adminer 中英文语言精简版本…...
go 中线程安全map
在 Go 语言中,官方包 sync.Map 确实提供了线程安全的映射数据结构。然而,正如你所提到的,使用 sync.Map 时,有时需要进行类型断言,这可能会让代码显得冗长或不直观。 如果你希望使用一个更加易用的线程安全映射&#…...
eslint 安装与使用-基础教程
中文官网 官方规则解析 规则参考 - ESLint - 插件化的 JavaScript 代码检查工具 eslint ESlint 是一个检查 JS,TS 语法的工具.能够与常用开发工具,例如 VS Code,进行集成并提供错误提示,和可能的修正方法 安装 安装eslint npm init esli…...
自然语言处理的未来愿景
自然语言处理的未来愿景 在这个信息爆炸的时代,计算机如何理解和生成我们日常使用的语言,已经成为一个引人注目的问题。你有没有想过,为什么智能助手能理解你的指令?又或者,为什么社交媒体上的推荐引擎能够精准地推荐你喜爱的内容?这背后,正是自然语言处理(NLP)在发挥…...
等保2.0三级测评华为华三交换机路由器
在使用本博客提供的学习笔记及相关内容时,请注意以下免责声明: 信息准确性:本博客的内容是基于作者的个人理解和经验,尽力确保信息的准确性和时效性,但不保证所有信息都完全正确或最新。 非专业建议:博客中的内容仅供参考,不能替代专业人士的意见和建议。在做出任何重要…...
BA和CS算法中的Levy飞行策略
Levy飞行策略通过模拟自然界中动物的长距离迁徙行为,指导粒子进行更大范围的搜索,有助于算法快速找到全局最优解。它是一种具有独特优势的随机行为策略,模拟随机游走或搜索过程中的步长和方向,其步长的概率分布为重尾分布…...
PHP:实现两张无关联表数据的联合分页处理方案
前言 在现代软件开发中,高效地处理数据是至关重要的环节。尤其是在使用 PHP 进行开发时,常常会遇到各种复杂的数据处理需求。其中,实现两张无关联表数据的联合分页处理就是一个具有挑战性的任务。这种需求在很多实际应用场景中都可能出现&am…...
【单元测试】单元测试介绍
1 单元测试基础 1.单元测试:单元测试又称模块测试,属于白盒测试,是最小单位的测试。模块分为程序模块和功能模块。功能模块指实现了一个完整功能的模块(单元),一个完整的程序单元具备输入、加工和输出三个…...
PyQt事件机制及其应用
一、实例前置 一个小闹钟应用 创建主窗口类 首先我们创建了一个名为AlarmClock的类,它继承自QMainWindow。这个类将包含我们的GUI组件和逻辑。 from Alarm_clock import Ui_MainWindowclass AlarmClock(QMainWindow):def __init__(self):super().__init__()# 初始化…...
厦门凯酷全科技有限公司抖音电商服务的卓越典范
在短视频和直播带货迅速崛起的时代,厦门凯酷全科技有限公司(以下简称“凯酷全科技”)以其专业的服务、创新的精神以及对市场的深刻理解,在抖音电商领域中脱颖而出,成为众多品牌商家信赖的选择。本文将深入探讨凯酷全科…...
vue3水波柱状图 ,实现
效果图 //引用页面 <div style"height: 60px;background-color: #fff;border-radius: 5px;width: 40px;"><WavePercentage:percentage"progress"primary-color"#ffcb7c"secondary-color"#ffcb7c"/></div>import Wa…...
如何在两台 PostgreSQL 服务器之间使用逻辑复制槽进行数据复制
如何在两台 PostgreSQL 服务器之间使用逻辑复制槽进行数据复制 如何在两台 PostgreSQL 服务器之间使用逻辑复制槽进行数据复制环境准备1. 配置主服务器(Publisher)1.1 修改 postgresql.conf1.2 修改 pg_hba.conf1.3 重启 PostgreSQL 服务1.4 创建逻辑复制…...
System.Data.OracleClient 需要 Oracle 客户端软件 version 8.1.7 或更高版本
问题1:“/”应用程序中的服务器错误。 System.Data.OracleClient 需要 Oracle 客户端软件 version 8.1.7 或更高版本。 说明: 执行当前 Web 请求期间,出现未经处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细…...
【机器人】振动分析和控制工具之Bode图
Bode 图完整介绍 Bode 图由两个部分组成: 幅值图 (Magnitude Plot):描述系统对不同频率输入信号的增益大小(幅值响应)。相位图 (Phase Plot):描述系统输出信号相对于输入信号的相位差。 Bode 图的横轴是频率&#x…...
生成:安卓证书uniapp
地址: https://ask.dcloud.net.cn/article/35777 // 使用keytool -genkey命令生成证书: 官网: keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore ----------------------------------…...
酒店/电影推荐系统里面如何应用深度学习如CNN?
【1】酒店推荐系统里面如何应用CNN?具体过程是什么 在酒店推荐系统中应用卷积神经网络(CNN)并不是一个常见的选择,因为 CNN 主要用于处理具有空间结构的数据,如图像、音频和某些类型的序列数据。然而,在某…...
【CSS in Depth 2 精译_069】11.3 利用 OKLCH 颜色值来处理 CSS 中的颜色问题(上)
当前内容所在位置(可进入专栏查看其他译好的章节内容) 第四部分 视觉增强技术 ✔️【第 11 章 颜色与对比】 ✔️ 11.1 通过对比进行交流 11.1.1 模式的建立11.1.2 还原设计稿 11.2 颜色的定义 11.2.1 色域与色彩空间11.2.2 CSS 颜色表示法 11.2.2.1 RGB…...
Redis篇-6--原理篇5--单线程模型
1、概述 Redis 采用单线程模型来处理客户端请求,这意味着在任意时刻只有一个命令被执行。这种设计简化了 Redis 的实现,并确保了高并发环境下的数据一致性。尽管 Redis 是单线程的,但它通过高效的内存管理和网络 I/O 操作,仍然能…...
Java版-图论-最小生成树-Prim算法
实现描述 如图: Prim算法的基本思想是从一个顶点开始,逐步构建最小生成树。具体步骤如下: 随机选取一个顶点作为起始点,并将其加入最小生成树的集合中。从该顶点出发,选择一条边连接到其他未被访问的顶点中的最小权…...
Python 基础学习(一)
一.基础语法 注释 Python中单行注释以 # 开头,如下: #!/usr/bin/python3# 第一个注释 print ("Hello, Python!") # 第二个注释多行注释可以用多个 # 号,还有 ‘’’ 和 “”": #!/usr/bin/python3# 第一个注释…...
vue2使用rtsp视频流接入海康威视摄像头(纯前端)
一.获取海康威视rtsp视频流 海康威视官方的RTSP最新取流格式如下: rtsp://用户名:密码IP:554/Streaming/Channels/101 用户名和密码 IP就是登陆摄像头时候的IP(笔者这里IP是192.168.1.210) 所以笔者的rtsp流地址就是rtsp://用户名:密码192.168.1.210:554/Streaming/Channel…...
利用PHP和GD库实现图片拼接的方法
利用PHP和GD库实现图片拼接的方法主要涉及到加载图片资源、创建目标画布、将图片资源绘制到目标画布上,并最终输出或保存拼接后的图片。以下是实现图片拼接的基本步骤: 加载图片资源: 使用imagecreatefromjpeg()、imagecreatefrompng()或ima…...
自动驾驶领域常用的软件与工具
CarSim:专门针对车辆动力学的仿真软件,能够预测和仿真汽车整车的操纵稳定性、制动性、平顺性、动力性和经济性。CarMaker:德国IPG公司推出的动力学、ADAS和自动驾驶仿真软件,提供精准的车辆本体模型和闭环仿真系统。VTD (Virtual …...
uniapp-内部项目使用文档
uniapp-内部项目使用文档 目录 uniapp-内部项目使用文档阶段1自行实现内容:阶段1问题记录: 阶段2自行实现内容: 阶段3 APP项目介绍及规范阶段4 公共组件方法UseList 列表页面HooksListItem 列表项uni-load-more 列表加载更多组件CardTitle 列…...
ASP .NET Core 中的环境变量
在本文中,我们将通过组织一场小型音乐会(当然是在代码中)来了解 ASP .NET Core 中的环境变量。让我们从创建项目开始: dotnet new web --name Concert 并更新Program.cs: // replace this: app.MapGet("/"…...
学科竞赛管理系统
文末获取源码和万字论文,制作不易,感谢点赞支持。 摘 要 随着国家教育体制的改革,全国各地举办的竞赛活动数目也是逐年增加,面对如此大的数目的竞赛信息,传统竞赛管理方式已经无法满足需求,为了提高效率&am…...
unity 让文字变形
效果: using TMPro; using UnityEngine; using NaughtyAttributes;[ExecuteInEditMode] public class TMTextPerpective : MonoBehaviour {[OnValueChanged("DoPerspective")][Range(-1f, 1f)]public float CenterBias 0f;[OnValueChanged("DoPers…...
Linux高并发服务器开发 第一天(Linux的目录结构 cd用法 终端提示符格式)
目录 1.命令解析器:shell 2.LINUX下的目录结构 3.cd的使用 3.1cd 绝对路径 3.2cd 相对路径 3.3cd 回车 3.4cd - 4. 终端提示符格式 1.命令解析器:shell 默认运行与计算机系统终端的 用来解析用户输入命令的工具 内核:操作系统的核…...
可造成敏感信息泄露!Spring Boot之Actuator信息泄露漏洞三种利用方式总结
1.介绍 Spring Boot是一个基于Spring的套件,它提供了一个即开即用的应用程序架构,可以简化Spring应用的创建及部署流程,帮助开发者更轻松快捷地构建出企业及应用。 Spring Boot项目中Actuator模块提供了众多HTTP接口端点(Endpoi…...
网站开发网站设计案例/seo培训师
ComboBox自定义数据源实现用户输入时出现与用户输入匹配的项using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace _2012_11_15Pra…...
dw做网站背景音乐/江门网站建设
最近在用element-ui遇到一些bug,在使用el-select时,数据量大了就页面渲染缓慢从而卡顿严重,为了解决这个问题,对element-ui进行了改造,el-select改为分页滚动加载: 如上图所示的效果,大数据时下拉可以分页滚动加载,而且可以支持原来的搜索。 1.新建一个selectSearch.v…...
怎么做网站免费的/常州网站建设制作
AAA认证及RADIUS配置 AAA简介 AAA是Authentication,Authorization and Accounting(认证、授权和计费)的简称,它提供了一个对认证、授权和计费这三种安全功能进行配置的一致性框架,实际上是对网络安全的一种管理。 这里…...
政府网站建设方面存在的问题及对策/代写文章
俗话说:大公司做人,小公司做事,当你的能力、格局等方方面面还不够“尖锐”、专业到可以独掌一面的时候,扎实沉在公司里,学习、沉淀、韬光养晦才是最靠谱的选择, 当然还有最主要的原因-养活自己。可惜的是&a…...
建设银行上海黄浦支行网站/应用关键词优化
本文介绍如何搭建四节点的Oracle Linux 7集群以及oozie的High Availability。环境如下图:一、创建HA集群1、安装集群软件包分别在4个节点上安装,如下: [roothdp01 ~]# yum install pcs fence-agents-all -y [roothdp02 ~]# yum install pcs…...
网站建设与管理课程视频/网络推广销售是做什么的
此HTML标签<input id"Radio1" type"radio"/>可完全取代以上2个服务器控件。RadioButtonList及RadioButton依赖于form窗体,产生很多垃圾代码,有时候只是用来显示此方法可取代。aspx:<input type"radio" name"…...