裸机:串口通信

embedded/2024/9/20 3:52:54/ 标签: 单片机, stm32, 嵌入式硬件

串口通信的基本原理

单工通信和双工通信
(1)单工就是单方向,双工就是双方同时收发,同时只能但方向但是方向可以改变叫半双工
(2)如果只能A发B收则单工,A发B收或者B发A收(两个方向不能同时)叫半双工,A发B收同时B发A收叫全双工。

三根通信线:Rx Tx GND
(1)任何通信都要有信息传输载体,或者是有线的或者是无线的。
(2)串口通信是有线通信,是通过串口线来通信的。
(3)串口通信线最少需要2根(GND和信号线),可以实现单工通信,也可以使用3根通信线(Tx、Rx、GND)来实现全双工。
(4)一般开发板都会引出SoC上串口引脚直接输出的TTL电平的串口(X210开发板没有),插座用插针式插座,每个串口引出的都有3个线(Tx、Rx、GND),可以用这些插座直接连接外部的TTL电平的串口设备。

收发双方事先规定好通信参数(波特率、数据位、奇偶校验位、停止位等)
(1)串口通信属于基层基本性的通信规约,它自己本身不会去协商通信参数,需要通信前通信双方事先约定好通信参数(一般4个最重要的)
(2)串口通信的任何一个关键参数设置错误,都会导致通信失败。譬如波特率调错了,发送方发送没问题,接收方也能接收,但是接收到全是乱码···

S5PV210的串口控制器工作原理框图

《S5PV210_UM_REV1.1》853页

在这里插入图片描述
(1)S5PV210的数据手册中串口控制器在section8.1
(2)串口的官方名称叫:universal asynchronous reciver and transmitter,通用异步收发器
英文缩写是uart,中文简称串口。

在这里插入图片描述
将来计算串口控制器的源时钟时是以APB总线来计算的。
整个串口控制器包含transmitter和receiver两部分,两部分功能彼此独立,transmitter负责210向外部发送信息,receiver负责从外部接收信息到210内部。

Transmitter(发送器)
组成:由发送缓冲区和发送移位器两部分构成。
工作流程优化描述:
信息编码:首先,待发送的信息被高效编码为ASCII码(或根据需求选择其他适合的编码方式)形式的二进制流。
缓冲区写入:随后,这一串二进制流被组织成帧,每帧通常包含8位(或其他预定义长度),并自动写入发送缓冲区。此过程无缝衔接,确保数据流的连续性。
自动发送:一旦数据被安全存入缓冲区,发送移位器即自动介入,无需CPU额外干预。它逐位地从缓冲区中读取数据帧,并通过精心设计的移位机制将每位数据依次发送到Tx(发送)通信线上。这一过程极大减轻了CPU的负担,提高了数据传输的效率和稳定性。

Receiver(接收器)
组成:由接收缓冲区和接收移位器两部分组成。
工作流程优化描述:
数据接收:当外部设备通过串口Rx(接收)通信线发送数据时,这些数据首先被接收移位器捕获。移位器迅速而准确地处理每一位进入的数据,通过内部移位操作将它们整理成有序的二进制位序列。
缓冲存储:整理好的二进制位序列被自动存储到接收缓冲区中,直到一帧完整的数据被接收完毕。此过程确保了数据的完整性和准确性。
中断通知:一旦一帧数据被完全接收并存储在缓冲区中,接收器会立即生成一个中断信号给CPU。这一设计允许CPU在需要时才介入处理数据,从而实现了资源的有效分配和系统的低功耗运行。CPU在接收到中断后,将响应该信号,从接收缓冲区中读取数据帧,进行后续处理。

串口控制器中有一个波特率发生器,作用是产生串口发送/接收的节拍时钟。波特率发生器其实就是个时钟分频器,它的工作需要源时钟(APB总线来),然后内部将源时钟进行分频(软件设置寄存器来配置)得到目标时钟,然后再用这个目标时钟产生波特率(硬件自动的)。

基本知识

自动流控(AFC:Auto flow control)是一种在数据传输过程中用于控制数据流速和确保数据完整性的机制。它主要用于串口通信中,特别是在发送方速率可能超过接收方处理能力的情况下,通过自动调整数据传输的速率来防止数据丢失。

FIFO模式及其作用
(1)典型的串口设计,发送/接收缓冲区只有1字节,每次发送/接收只能处理1帧数据。这样在单片机中没什么问题,但是到复杂SoC中(一般有操作系统的)就会有问题,会导致效率低下,因为CPU需要不断切换上下文。
(2)解决方案就是想办法扩展串口控制器的发送/接收缓冲区,譬如将发送/接收缓冲器设置为64字节,CPU一次过来直接给发送缓冲区64字节的待发送数据,然后transmitter慢慢发,发完再找CPU再要64字节。但是串口控制器本来的发送/接收缓冲区是固定的1字节长度的,所以做了个变相的扩展,就是FIFO。
(3)FIFO就是first in first out,先进先出。fifo其实是一种数据结构,这里这个大的缓冲区叫FIFO是因为这个缓冲区的工作方式类似于FIFO这种数据结构。

DMA模式及其作用
(1)DMA direct memory access,直接内存访问。DMA本来是DSP中的一种技术,DMA技术的核心就是在交换数据时不需要CPU参与,模块可以自己完成。
(2)DMA模式要解决的问题和上面FIFO模式是同一个问题,就是串口发送/接收要频繁的折腾CPU造成CPU反复切换上下文导致系统效率低下。
(3)传统的串口工作方式(无FIFO无DMA)效率是最低的,适合低端单片机;高端单片机上CPU事物繁忙所以都需要串口能够自己完成大量数据发送/接收。这时候就需要FIFO或者DMA模式。FIFO模式是一种轻量级的解决方案,DMA模式适合大量数据迸发式的发送/接收时。

IrDA模式及其用法
(1)IrDA其实就是红外,红外就是红外线通信(电视机、空调遥控器就是红外通信的)。
(2)红外通信的原理是发送方固定间隔时间向接收方发送红外信号(表示1或0)或者不发送红外信号(表示0或者1),接收方每隔固定时间去判断有无红外线信号来接收1和0.
(3)分析可知,红外通信和串口通信非常像,都是每隔固定时间发送1或者0(判断1或0的物理方式不同)给接收方来通信。因此210就利用串口通信来实现了红外发送和接收。
(4)210的某个串口支持IrDA模式,开启红外模式后,我们只需要向串口写数据,这些数据就会以红外光的方式向外发射出去(当然是需要一些外部硬件支持的),然后接收方接收这些红外数据即可解码得到我们的发送信息。

串行通信与中断的关系

(1)串口通信分为发送/接收2部分。发送方一般不需要(也可以使用)中断即可完成发送,接收方必须(一般来说必须,也可以轮询方式接收)使用中断来接收。
(2)发送方可以选择使用中断,也可以选择不使用中断。使用中断的工作情景是:发送方先设置好中断并绑定一个中断处理程序,然后发送方丢一帧数据给transmitter,transmitter发送耗费一段时间来发送这一帧数据,这段时间内发送方CPU可以去做别的事情,等transmitter发送完成后会产生一个TXD中断,该中断会导致事先绑定的中断处理程序执行,在中断处理程序中CPU会切换回来继续给transmitter放一帧数据,然后CPU切换离开;不使用中断的工作情景是:发送方事先禁止TXD中断(当然也不需要给相应的中断处理程序了),发送方CPU给一帧数据到transmitter,然后transmitter耗费一段时间来发送这帧数据,这段时间CPU在这等着(CPU没有切换去做别的事情),待发送方发送完成后CPU再给它一帧数据继续发送直到所有数据发完。CPU是怎么知道transmitter已经发送完了?原来是有个状态寄存器,状态寄存器中有一个位叫发送缓冲区空标志,transmitter发送完成(发送缓冲区空了)就会给这个标志位置位,CPU就是通过不断查询这个标志位为1还是0来指导发送是否已经完成的。
(3)因为串口通信是异步的,异步的意思就是说发送方占主导权。也就是说发送方随时想发就能发,但是接收方只有时刻等待才不会丢失数据。所以这个差异就导致发送方可以不用中断,而接收方不得不使用中断模式。

210串行通信接口的时钟设计

(1)串口通信为什么需要时钟?因为串口通信需要一个固定的波特率,所以transmitter和receiver都需要一个时钟信号。
(2)时钟信号从哪里来?源时钟信号是外部APB总线(PCLK_PSYS,66MHz)提供给串口模块的(这就是为什么我们说串口是挂在APB总线上的),然后进到串口控制器内部后给波特率发生器(实质上是一个分频器),在波特率发生器中进行分频,分频后得到一个低频时钟,这个时钟就是给transmitter和receiver使用的。
(3)串口通信中时钟的设置主要看寄存器设置。重点的有:寄存器源设置(为串口控制器选择源时钟,一般选择为PCLK_PSYS,也可以是SCLK_UART),还有波特率发生器的2个寄存器。
(4)波特率发生器有2个重要寄存器:UBRDIVn和UDIVSLOTn,其中UBRDIVn是主要的设置波特率的寄存器,UDIVSLOTn是用来辅助设置的,目的是为了校准波特率的。

代码实现

始化串口的Tx和Rx引脚所对应的GPIO(查原理图可知Rx和Rx分别对应GPA0_1和GPA0_0)
在这里插入图片描述
主要的几个寄存器
(1)ULCON0(ULCON0, R/W, Address = 0xE290_0000) = 0x3 // 0校验位、8数据位、1停止位
(2)UCON0(R/W, Address = 0xE290_0004) = 0x5 // 发送和接收都是polling mode
(3)UMCON0(UMCON0, R/W, Address = 0xE290_000C) = 0x0 // 禁止modem、afc
(4)UFCON0(UFCON0, R/W, Address = 0xE290_0008) = 0x0 // 禁止FIFO模式
(5)UBRDIV0(UBRDIV0, R/W, Address = 0xE290_0028)和UDIVSLOT0(UDIVSLOT0, R/W, Address = 0xE290_002C)和波特率有关,要根据公式去算的

#define GPA0CON		0xE0200000
#define UCON0 		0xE2900004
#define ULCON0 		0xE2900000
#define UMCON0 		0xE290000C
#define UFCON0 		0xE2900008
#define UBRDIV0 	0xE2900028
#define UDIVSLOT0	0xE290002C
#define UTRSTAT0	0xE2900010
#define UTXH0		0xE2900020	
#define URXH0		0xE2900024	

GPA0CON:
用于配置端口A的第0组引脚的功能(如输入、输出、特殊功能等)。
UCON0:
UART控制寄存器0的地址。这个寄存器用于控制UART0的基本操作,如设置UART的模式(如中断模式、轮询模式)、设置波特率生成器、使能UART接收/发送等。
ULCON0:
UART线路控制寄存器0的地址。这个寄存器用于设置UART的线路控制特性,如数据位长度、停止位数量、奇偶校验位等。
UMCON0:
UART调制控制寄存器0的地址。这个寄存器可能用于控制UART的流控制(如软件流控制RTS/CTS)或其他调制相关的功能。
UFCON0:
UART FIFO控制寄存器0的地址。FIFO(先进先出)是一种用于缓冲数据的队列结构,这个寄存器用于控制UART的FIFO缓冲区,如使能/禁用FIFO、设置FIFO触发级别等。
UBRDIV0:
UART波特率除数寄存器0的地址。这个寄存器用于设置UART的波特率除数,通过调整这个值,可以调整UART通信的波特率。
UDIVSLOT0:
UART除法槽寄存器0的地址。这个寄存器可能用于更精细地调整UART的波特率,特别是在需要非常精确的波特率设置时。
UTRSTAT0:
UART传输/接收状态寄存器0的地址。这个寄存器提供了UART传输和接收操作的状态信息,如是否有数据可读、发送缓冲区是否空等。
UTXH0:
UART发送缓冲区寄存器0的地址。这个寄存器用于存放要发送的数据,当UART发送器准备好时,它会从这个寄存器中读取数据并发送出去。
URXH0:
UART接收缓冲区寄存器0的地址。这个寄存器用于存放接收到的数据,当UART接收器接收到数据时,它会将数据存放在这个寄存器中,供CPU读取。

波特率的计算

DIV_VAL = (PCLK / (bps x 16)) −1
在这里插入图片描述余数决定UDIVSLOTn
0.816 = 12.8 选 0xDFDD
0.18
16 =2.88 选0x0888在这里插入图片描述

//初始化
void uart_init(void)
{// 初始化 Tx Rx 对应的引脚rGPA0CON &= ~(0xff<<0);			//把寄存器的bit0~7全部清零rGPA0CON |= 0x00000022;			// 0b0010, Rx Tx// 关键寄存器配置rULCON0 = 0x3;// 0校验位、8数据位、1停止位rUCON0 = 0x5;// 发送和接收都是polling moderUMCON0 = 0;// 禁止modem、afcrUFCON0 = 0;// 禁止FIFO模式// 波特率公式	DIV_VAL = (PCLK / (bps x 16))-1// PCLK_PSYS=66MHz		余数0.8 // DIV_VAL = (66000000/(115200*16)-1) = 34.80//rUBRDIV0 = 34;	//rUDIVSLOT0 = 0xdfdd;//0.8*16 = 12.8 选 0xDFDD// PCLK_PSYS=66.7MHz		余数0.18 // DIV_VAL = (66700000/(115200*16)-1) = 35.18rUBRDIV0 = 35;//例子 (num of 1's in UDIVSLOTn)/16 = 0.7 -》UDIVSLOTn= 余数*19=6按照表格找值rUDIVSLOT0 = 0x0888;		// 0.18*16 =2.88 选0x0888
}

波特率的计算和设置
(1)第一步,用PCLK_PSYS和目标波特率去计算DIV_VAL: DIV_VAL = (PCLK / (bps x 16)) -1
(2)第二步,UBRDIV0寄存器中写入DIV_VAL的整数部分
(3)第三步,用小数部分*16得到1个个数,查表得uBDIVSLOT0寄存器的设置值

串口发送和接收函数的编写
(1)写发送函数,主要发送前要用while循环等待发送缓冲区为空才能发送。

//发送一个字节
void uart_putc(char c)
{//因为串口控制器发送1个字节的速度远低于CPU的速度,所以CPU发送1个字节前必须//确认串口控制器当前缓冲区是空的(意思就是串口已经发完了上一个字节//如果缓冲区非空则位为0,此时应该循环,直到bit1位为1while (!(rUTRSTAT0 & (1<<1)));//硬件判断是否发送结束 bit1 rUTXH0 = c;  //串口发送一个字符,其实就是把一个字节丢到发送给冲区中去}

下载程序验证成功

在这里插入图片描述
在这里插入图片描述

uart stdio的移植

什么是stdio
(1)#include <stdio.h>
(2)stdio:standard input output,标准输入输出
(3)标准输入输出就是操作系统定义的默认的输入和输出通道。一般在PC机的情况下,标准输入指的是键盘,标准输出指的是屏幕。
(4)printf函数和scanf函数可以和底层输入/输出函数绑定,然后这两个函数就可以和stdio绑定起来。也就是说我们直接调用printf函数输出,内容就会被从标准输出输出出去。
(5)在我们这里,标准输出当然不是屏幕了,而是串口。标准输出也不是键盘,而是串口。

printf函数的工作原理
(1)printf函数工作时内部实际调用了2个关键函数:一个是vsprintf函数(主要功能是格式化打印信息,最终得到纯字符串格式的打印信息等待输出),另一个就是真正的输出函数putc(操控标准输出的硬件,将信息发送出去)

移植printf函数的三种思路
(1)我们希望在我们的开发板上使用printf函数进行(串口)输出,使用scanf函数进行(串口)输入,就像在PC机上用键盘和屏幕进行输入输出一样。因此需要移植printf函数/scanf函数
(2)我们说的移植而不是编写,我们不希望自己完全从新编写而是想尽量借用也有的代码(叫移植)
(3)一般移植printf函数可以有3个途径获取printf的实现源码:最原始最原本的来源就是linux内核中的printk。难度较大、关键是麻烦;稍微简单些的方法是从uboot中移植printf;更简单的方法就是直接使用别人移植好的。
(3)我们课程中使用第三种方法,别人移植好的printf函数来自于友善之臂的Tiny210的裸机教程中提供的。

主要是将修改Makefile,将别人的代码添加进来

CC		= arm-linux-gcc
LD 		= arm-linux-ld
OBJCOPY	= arm-linux-objcopy
OBJDUMP	= arm-linux-objdump
AR		= arm-linux-arINCDIR	:= $(shell pwd)
# C预处理器的flag,flag就是编译器可选的选项
CPPFLAGS	:= -nostdlib -nostdinc -I$(INCDIR)/include
# C编译器的flag
CFLAGS		:= -Wall -O2 -fno-builtin#导出这些变量到全局,其实就是给子文件夹下面的Makefile使用
export CC LD OBJCOPY OBJDUMP AR CPPFLAGS CFLAGSobjs := start.o led.o clock.o uart.o main.o
objs += lib/libc.auart.bin: $(objs)$(LD) -Tlink.lds -o uart.elf $^$(OBJCOPY) -O binary uart.elf uart.bin$(OBJDUMP) -D uart.elf > uart_elf.disgcc mkv210_image.c -o mkx210./mkx210 uart.bin 210.binlib/libc.a:cd lib;	make;	cd ..%.o : %.S$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< -c%.o : %.c$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< -cclean:rm *.o *.elf *.bin *.dis mkx210 -fcd lib; make clean; cd ..

在这里插入图片描述

学习记录,侵权联系删除。
来源:朱老师物联网大课堂


http://www.ppmy.cn/embedded/100759.html

相关文章

帆软报表,达梦数据库驱动上传失败

1、按照正常操作新建数据库连接&#xff0c;上传准备好的达梦驱动时&#xff0c;提示如图一需要修改SystemConfig.driverUpload为true才可以。 2、FineDB存储了数据决策系统中除平台属性配置以外的所有信息。详情请参见&#xff1a; FineDB 数据库简介。 3、因此管理员可通过…

【精选】基于Python大型购物商城系统(京东购物商城,淘宝购物商城,拼多多购物商城爬虫系统)

目录&#xff1a; 目录&#xff1a; 系统介绍&#xff1a; 系统开发技术 Python语言 Django框架简介 MySQL数据库技术 B/S架构 系统设计 系统总体设计 系统详细界面实现&#xff1a; 系统测试 测试目的 测试用例 本章小结 参考代码&#xff1a; 为什么选择我&…

SpringBoot整合MQ

一、消息的概 从广义角度来说&#xff0c;消息其实就是信息&#xff0c;但是和信息又有所不同。信息通常被定义为一组数据&#xff0c;而消息除了具有数据的特征之外&#xff0c;还有消息的来源与接收的概念。通常发送消息的一方称为消息的生产者&#xff0c;接收消息的一方称为…

C语言 ——— 经典有关动态内存的笔试题

目录 笔试题1 笔试题2 笔试题3 笔试题1 代码演示&#xff1a; #include<stdio.h> #include<string.h> void GetMemory(char* p) {p (char*)malloc(100); } void Test() {char* str NULL;GetMemory(str);strcpy(str, "hello world");printf("…

C++ | Leetcode C++题解之第371题两整数之和

题目&#xff1a; 题解&#xff1a; class Solution { public:int getSum(int a, int b) {while (b ! 0) {unsigned int carry (unsigned int)(a & b) << 1;a a ^ b;b carry;}return a;} };

工厂现场多功能帮手,三防平板改善管理体验

随着制造业的智能化变革&#xff0c;信息化、自动化和智能化逐渐成为工厂管理的新常态。在这一波技术浪潮中&#xff0c;三防平板作为一种多功能的工作工具&#xff0c;正在逐步改善工厂现场的管理体验。 一、三防平板的定义与特点 三防平板&#xff0c;顾名思义&#xff0c;是…

02_React面向组件编程--基本使用与理解、组件实例的三大核心属性与事件处理

基本使用与理解、组件实例的三大核心属性与事件处理 一、基本理解与使用1、函数式组件2、类的复习3、类式组件4、简单组件和复杂组件 二、组件实例的三大核心属性 1&#xff1a;state1、例子&#xff0c;点击文字切换 凉爽和炎热1.1 复习--原生事件绑定方式1.2 复习--类中的方法…

Redis篇一:初识Redis

文章目录 前言1. 初始Redis2. MySQL VS Redis3. 什么是分布式系统&#xff08;也是一种处理大量数据时的处理方式&#xff09;3.1 单机架构3.2 数据库与应用服务分离3.3 负载均衡3.4 数据库读写分离3.5 引入缓存&#xff08;Redis&#xff09;3.6 数据库分库分表3.7 引入微服务…

网络udp及ipc内存共享

大字符串找小字符串 调试 1. 信号处理函数注册&#xff1a;•一旦使用 signal 函数注册了信号处理函数&#xff0c;该函数就会一直有效&#xff0c;直到程序结束或者显式地取消注册。2. 注册多次的影响&#xff1a;•如果多次注册同一信号的处理函数&#xff0c;最后一次注册的…

Java RPC、Go RPC、Node RPC、Python RPC 之间的互相调用

Java RPC、Go RPC、Node RPC、Python RPC 之间的互相调用是完全可以实现的&#xff0c;但需要满足一些条件和依赖于特定的工具和协议。以下是如何实现不同语言之间的RPC互相调用的详细解释&#xff1a; 1. 使用通用协议和标准&#xff1a;gRPC gRPC 是一个高性能、开源的RPC框…

SSRF漏洞——pikachu

环境搭建 pikachu文件如下&#xff1a; 通过百度网盘分享的文件&#xff1a;pikachu-master.zip 链接&#xff1a;https://pan.baidu.com/s/1HuV2llJzx1c7Ii6u-r4s3Q?pwdqwer 提取码&#xff1a;qwer 解压至小皮WWW文件夹下&#xff0c;进入config.inc.php中修改MySQL名字…

深信达反向沙箱:构筑内网安全与成本效益的双重防线

# 深信达反向沙箱&#xff1a;内网安全与成本控制的双重保障 在数字化时代&#xff0c;企业面临着日益复杂的网络安全挑战。内网安全尤其关键&#xff0c;因为它涉及到企业的核心数据和运营。深信达的反向沙箱技术&#xff0c;作为一种创新的安全解决方案&#xff0c;为政企单…

基于Android的运动记录APP设计与实现(论文+源码)_kaic

摘要 随着人们生活水平和生活质量的提高&#xff0c;人们越来越关注自己的身体健康。而跑步成为人们最受欢迎的运动方式&#xff0c;运动软件可以在人们锻炼身体的时候提供极大的帮助。本文针对运动轨迹和计步&#xff0c;设计一款基于Android 平台的运动软件。本系统通过使用百…

【OCPP】ocpp1.6协议第5.14 Reset章节的介绍及翻译

目录 5.14 重置Reset-概述 概述 消息格式 操作流程 重置类型 消息示例 错误处理 注意事项 安全性 5.14 重置Reset-原文译文 5.14 重置Reset-概述 在OCPP 1.6协议中,第5.14章节“Reset”主要讲述了中央系统(CSMS, Central System)如何向充电站(CS, Charge Statio…

培训第三十二天(学习playbook-roles,脚本创建数据库和表,mycat读写分离)

上午 1、roles&#xff08;角色&#xff09;介绍 roles(⻆⾊): 就是通过分别将variables, tasks及handlers等放置于单独 的⽬录中,并可以便捷地调⽤它们的⼀种机制。 假设我们要写⼀个playbook来安装管理lamp环境&#xff0c;那么这个 playbook就会写很⻓。所以我们希望把这…

ES详细使用!Elasticsearch实现索引操作,增删改查,批处理

要想知道ES怎么具体实现对数据的操作&#xff0c;我们首先应该了解一下什么叫做restful编码风格&#xff0c;因为es的具体操作都是restful风格的。 1.RESTful风格 RESTful 是一种软件架构风格&#xff0c;用于创建可扩展的网络服务。它使用 HTTP 方法&#xff08;如 GET、POS…

C++竞赛初阶L1-13-第五单元-循环嵌套(29~30课)538: T456457 第 n 小的质数

题目内容 输入一个正整数 n&#xff0c;求正整数范围中第 n 小的质数。 输入格式 一个不超过 30000 的正整数 n。 输出格式 第 n 小的质数。 样例 1 输入 10 全部程序代码&#xff1a; #include<bits/stdc.h> using namespace std; int main() {long long n,i;ci…

StarRocks 存算分离数据回收原理

前言 StarRocks存算分离表中&#xff0c;垃圾回收是为了删除那些无用的历史版本数据&#xff0c;从而节约存储空间。考虑到对象存储按照存储容量收费&#xff0c;因此&#xff0c;节约存储空间对于降本增效尤为必要。 在系统运行过程中&#xff0c;有以下几种情况可能会需要删…

Linux运维、Windows运维常用命令,保存起来当手册用

文章目录 一、centos基本命令1、升级内核到最新版本2、文件句柄数限制优化3、ssh、sftp、scp等远程命令4、find文件查找5、vi命令 二、windows常用操作 一、centos基本命令 1、升级内核到最新版本 # 1、查看内核版本 [rootlocalhost ~]# cat /etc/centos-release CentOS Linu…

关于Spring Boot的自动配置

目录 1.EnableAutoConfiguration注解 2.SpringBootConfiguration注解 3.Import注解 4.spring.factories 5.总结 &#xff08;1&#xff09;EnableAutoConfiguration &#xff08;2&#xff09;AutoConfigurationImportSelector &#xff08;3&#xff09; SpringFactoriesLoade…