【STM32】 TCP/IP通信协议(1)--LwIP介绍

news2024/12/29 14:17:11

一、前言

TCP/IP是干啥的?它跟SPI、IIC、CAN有什么区别?它如何实现stm32的通讯?如何去配置?为了搞懂这些问题,查询资料可解决如下疑问:

1.为什么要用以太网通信?

以太网(Ethernet) 是指遵守 IEEE 802.3 标准组成的局域网,是互联网技术的一种,由于它是在组网技术中占的比例最高,很多人直接把以太网理解为互联网。但是,IEEE 还有其它局域网标准,如 IEEE 802.11 是无线局域网,俗称 Wi-Fi。IEEE802.15 是个人域网,即蓝牙技术,其中的 802.15.4 标准则是 ZigBee 技术。(想具体了解的可以浏览这篇博客http://t.csdnimg.cn/3oz5b)

工业以太网是在以太网技术和Tcp/ip技术的基础上开发出来的一种工业网络,在工业当中,由于以太网的用户培训成本低、产品技术成熟、价格低供应稳定、信息集成容易等优势,应用范围比较广,因此在STM32上使用还是很重要的。

以太网所用的协议则是TCP/IP通信协议

2.什么是TCP/IP?

TCP/IP是一个庞大的协议族,是众多网络协议的集合,还包括:ARPIPICMPUDPTCPDNSDHCPHTTP、FTP、MQTT等等。TCP/IP 协议栈中不同协议所完成的功能是不一样的, 某些协议的实现要依赖于其它协议,依据这种依赖关系,可以将协议栈分层。低层协议为相邻的上层协议提供服务,是上层协议得以实现的基础。

3.TCP/IP分层模型是什么?

TCP/IP分成四层:应用层传输层网络层网络接口层。分层就是让不同的底层网卡可以独立实现自己的功能,比如物理层提供二进制传输、实现编码为网络层提供标准的接口,当然内部如何实现无需在意。

传输过程:举个例子:加入你发送QQ消息给朋友A,“周末出来玩吗?”,按下“发送”或者回车键时,计算机如何将这些信息传输过去呢?

你发送消息:

(1)应用层:发现你传输的数据有一条文字信息,于是做好了标记,加上应用层首部,传送到传输层。

(2) 传输层:由于对方也需要用QQ接收你发来的消息,因此就用到了“端口”(电脑上有很多程序,不同程序由不同的端口来识别),于是做好端口标记,再加上TCP首部,跟之前的部分形成TCP,送往网络层

(3) 网络层:由于网路是由无数的子网层成的,要想把信息发送到对方的电脑中,就得用到IP地址,把数据送到相应的子网中找到对应的IP地址(IP地址包括网络号和主机号,网络号相同则判断在同一个子网下)的电脑。于是做好标记,加上IP首部,与之前的部分形成IP数据包,送到链路层。

(4)数据链路层:连入网络的每个计算机都会有网卡接口,每个网卡都会有一个唯一的地址,名叫“MAC地址”。计算机之间的数据传输就是通过MAC地址来唯一寻找并传送的(MAC地址由48位二进制所构成,在网卡生产时就唯一标识了)。所以当我们需要发送数据时,不仅要找到电脑主机,还要知道 MAC地址。假设ARP协议帮我们找到目标主机的MAC地址,但有时候发送的信息有些大,一次发送不出去,这是链路层便会切开成一组一组的,并一次次发送出去。

(5)物理层:收到数据链路层的数据,根据二进制划分为高低电平进行传输。

朋友A接收消息:

(1)物理层:0101....的电平信号经过,物理层把数据接收给链路层。

(2)链路层:如果MAC地址相匹配,便会排序查看数据是否有问题,没问题就拆掉以太网首部,把剩下的交给IP层。

(3)IP层:发现有数据,就拆掉IP首部,交给传输层

(4)传输层:发现目的地是送往是QQ端口,于是拆掉TCP首部,交给应用层

(5)应用层:QQ页面显示“周末出来玩吗?”

4.LwIP是什么?和TCP/IP有什么关系?

(1)LWIP的定义:

Light weight IP,顾名思义是一个轻量化的TCP/IP协议,由瑞典计算机科学院(SICS)的ADam Dunkels开发的一个小型开源的TCP/IP协议栈

(2)LWIP设计目的:用少量的资源消耗实现一个较为完整的TCP/IP协议栈。能用于云台接入、无线网关、远程模块、工控控制器、路由器、摄像头

(3)LWIP与TCP/IP的区别:

【1】LWIP并没有实现TCP/IP的全部功能

【2】极大地减少了对RAM的占用

【3】LWIP既可以移植到操作系统上运行,也可以在无操作系统的情况下独立运行

【4】LWIP并没有采用很明确的分层结构,它假设各层之间的部分数据和结构体和实现原理在其他层是可见的,简单来说就传输层知道IP层是如何封装数据、传递数据的,IP层知道链路层是怎么封装数据的等等,可以实现内存区域共用,极大避免数据拷贝,尽可能减少占用。

(4)LWIP的特点:

【1】资源开销低,高度可以剪裁,一切不需要的功能都可以通过红变异选项去掉,LWIP的流畅运行需要40KB的代码ROM的几十KB的RAM

【2】支持的协议较为完整

【3】实现了一些常见的应用程序,DHCP客户端、DNS客户端、HTTP服务器等

【4】提供了三种编程接口:RAW/Callback API(适合少任务、交互数据量少、数据处理时间开销小的场合)、NETCONN API(就是Sequential API,适合多任务、大数据量、大型应用)和 Socket API(是对NETCONN API的简单封装、更简单、但效率低、功能不完整)

【5】高度可移植。其源代码全部用 C 实现 ​ 【6】开源、免费,用户可以不用承担任何商业风险地使用它 ​ 【7】发展历史长

5.LwIP协议栈?

协议栈是协议的具体实现形式,通俗来讲就是用代码实现的库函数,从而让开发人员调用。因此我们在LWIP官网下载最新版,然后把里面的代码文件服战在自己的工程当中,然后用LWIP提供给用户的接口函数在字节的程序里实现TCP通信的功能。

6.TCP的“三次握手”和“四次挥手”是什么意思?

TCP是一种面向连接的传输协议,通俗来讲,UDP就像你妈在楼下扯一嗓子让你下楼帮忙,所有人都听得到,而且你也容易听不清;而TCP就像你妈打电话给你,信息传输一对一且稳定。

“三次握手”是确认连接的方式: 通俗来讲就是用三次发送来让双方确认自己与对方的发送与接收是正常的。 第一次 A:我要和B通信 第二次 B:好,我可以和你通信(当A收到这段话时,A已经确认了连接的可靠性,但B还不能确认A能否听到自己的回话) 第三次:A:我能听到你的回话,可以开始了。(这时候双方都确认了连接的可靠性) 如果握手尝试5次都没回应,就断开。

“四次挥手”是确认断开连接的方式: 通俗来讲就是用四次发送来让双方都确认连接的断开。 第一次 A:我要去忙别的了,不和你说了 第二次 B:我这句话还有一半没讲完呢,你听我说完再走 第三次 B:好的我说完了,你去忙吧 第四次 A:好的,我走了(A发完后会停留2毫秒,如果收到B的释放报文,说明B已经收到了释放信号,连接断开) 如果B没收到第四次挥手,就会重复发送第三次的释放信号,A发完后会停留2毫秒,如果还受到了B的第三次挥手信号,说明B没收到第四次挥手,这时候会A会再次重复第四次挥手。

img

二、STM32F4以太网MAC简介

以太网MAC存在于TCPIP栈中的数据链路层上。STM32F4自带有10/100Mbit/s的以太网MAC内核,

这个以太网MAC内核有如下特性:

  1. 支持外部PHY接口实现10M/100Mbit/s数据传输速率

  2. 通过符合IEEE802.3的MII接口与外界快速以太网PHY进行通信

  3. 支持全双工和半双工操作

  4. 报头和帧起始数据(SFD)在发送路径中插入、在接收员路径中删除

  5. 可逐帧控制CRC和pad自动生成

  6. 可编程帧长度,支持高达16kB的巨型帧...

由图中我们可以知道:

数据从芯片出发,通过以太网DMA传输,由FIFO寄存器收发,经过MAC,再通过时钟线MDC和数据线MDIO发送给外部PHY。

以太网接收发送FIFO数据寄存器的大小为2KB(发送的数据不能超过1500个字节)以及STM32F4的以太网与外部PHY通过RMII接口MII接口管理

F4的MAC接口有3个接口:SMI、MII、RMII

1. 站管理接口:SMI

程序中可以通过这个接口来访问PHY寄存器,SMI接口有两根线:数据线MDIO和时钟线MDC,该接口支持访问多达32个PHY

MDC:周期性时钟,提供以最大频率2.5Mhz传输数据时的参考时序,在空闲状态下,SMI管理接口将MDC时钟信号驱动为低电平

MDIO:数据输入/输出比特流,用于通过MDC时钟信号向/从PHY设备同步传输状态信息。

管理帧格式:(STM32F4XX中文参考手册P825)

PADDR:PHY地址

RADDR:寄存器地址

数据位:16位数据位(PHY寄存器都是16位的)

2. 介质独立接口:MII

介质独立接口(MII)定义了10Mbit/s和100Mbit/s的数据传输速率下,以太网内核与PHY设备之间的连接

TX_CLK和RX_CLK为发送和接收连续时钟,当速率为10Mbit/s时为2.5MHZ,速率为100Mbit/s时为25MHZ

要生成TX_CLK和RX_CLK时钟,必须向外部PHY提供25MHZ时钟,通常我们使用25M的晶振,也可以使用STM32F4xx的MCO的引脚输出25MHZ的时钟

3. 精简介质独立接口:RMII

精简介质独立接口 (RMII) 规范降低了 10/100 Mbit/s 下微控制器以太网外设与外部 PHY 间的引脚数。根据 IEEE 802.3u 标准,MII 包括 16 个数据和控制信号的引脚。RMII 规范将引脚数减少为 9 个。

MAC和PHY的参考时钟必须都是 50 MHz!

三、PHY层芯片LAN8720

RJ45 <-> PHY芯片 <-> 以太网MAC

是一个低功耗的10/100M以太网PHY层芯片,使用RMII接口和以太网MAC层进行通信,内置全双工模块,支持10Mbps和100Mbps。可以通过自卸调的方式与目的主机最佳的连接方式。支持自动翻转功能,无需更换网线即可将连接更改为直连或交叉连接。

LAN8720A-CP-TR_MICROCHIP(美国微芯)-LAN8720A-CP-TR中文资料_PDF手册_价格-立创商城

1.原理图

(1)STM32引脚:

(2)EARTHNET:

(3)RJ45:

(4)PCF8574

io扩展芯片

2.LAN8920说明

(1)PHY地址

上文有说MAC可以通过SML接口连接32个PHY芯片,那如何识别这32个PHY呢?就是通过PHY地址来区别的。

由于三(2)的原理图中第10号引脚浮空,默认为地址0x00

(2)RMII模式设置

LAN8720在RMII模式下可以设置两种连接模式:

REF_CLK输入模式(nINT)和REF_CLK输出模式。

配置模式决定了nINT / REFCLKO引脚的功能。 nINTSEL配置带锁定在POR和nRST的上升沿。默认情况下,通过内部上拉电阻将nINTSEL配置为nINT模式。

表带值模式REF_CLK说明
nINT引脚 = 0REF_CLK输出模式作为REF_CLK时钟源
nINT引脚 = 1REF_CLK输入模式作为中断引脚

REF_CLK来自外部,必须在XTAL1 / CLKIN引脚上驱动。

i. REF_CLK输入模式

在REF_CLK输入模式下,XTAL1/CLKIN引脚驱动50 MHz REF_CLK。使用该模式时,必须在器件外部提供用于REF_CLK的50 MHz源。如图所示,时钟同时驱动到MAC和PHY。

在这里插入图片描述

ii.REF_CLK输出模式

为了降低BOM成本,该器件具有从低成本25 MHz晶体生成RMII REF_CLK信号的功能。与通常需要50 MHz的第三泛音晶体相比,这种类型的晶体便宜。 MAC必须能够与外部时钟一起使用,才能利用此功能。

从25 MHZ晶体中获取REF_CLK

在这里插入图片描述

在某些系统架构中,可以使用25 MHz的时钟源。该器件可用于为MAC生成REF_CLK,在此特定示例中,只能使用25 MHz的时钟(时钟不能为50 MHz)。与25 MHz晶振模式相似,nINT功能被禁用。

外部25 MHZ源获得REF_CLK

在这里插入图片描述

3.PHY寄存器

LAN8720有32个寄存器,每个寄存器都有16位。

这32个寄存器中分为两类:

类似的寄存器:根据IEEE标准定义0~15寄存器(重点BCR和BSR寄存器根据用户实现的功能来设置)

自由定义的寄存器:16~31寄存器是由芯片制造商自由定义(一般无需修改)

在正点原子案例代码中

PHY_SR=0X1F 指的是第31位的寄存机(也就是上图寄存器)

PHY_SPEED_STATUS=0X0004 指的是PHY的速度为100Mbit/s(根据上图寄存器配置而成)

PHY_DUPLEX_STATUS=0X0010 指的是半双工传输模式(根据上图寄存器配置而成)

4.以太网DMA描述符

学过STM32-DMA内容的同学们都应该知道DMA是不需要CPU的参与就可以实现内存和外设之间的数据交换。同样的,对于STM32互联型单片机的以太网DMA的作用也是如此,它的作用就是在不需要CPU的参与下,实现内存和以太网外设的数据交换。通俗来说,就是我们将要发送的数据放在一片内存去,告诉以太网DMA,我已经将数据放过去了,你去取出来发送到网络中去;当网络数据来的时候,以太网DMA自动将数据拷贝到一片内存中,通过中断的方式告诉CPU,数据来了,你去取出来吧。

发送:不需要CPU的参与下,把描述符指向的缓冲区数据传输到TX FIFO当中

接收:不需要CPU的参与下,将RX FIFO的数据传输到描述符指向的缓冲区当中

描述符分为:

        常规描述符:管理缓冲区

        增强描述符:在常规描述符基础上开启时间戳和IPV4(内容不讲)

描述符不是实际存在的物理结构,而是在程序中通过软件实现的,其实就是一个结构体

常规描述符的结构体代码:

TX DMA描述符成员变量:

  • TDES0[31]置0:CPU可将数据拷贝到描述符中,拷贝完成之后把该位置为1,告诉DMA可以发送出去了

  • TDES0[20]置1:描述符中的第二个地址是下一个描述符地址【ST以太网驱动库是TDES0[20]置1】

  • TDES0[28:16]:如果TDES0[20]位置为1,则该字段无效

  • TDES0[31:0]:取决于TDES0[20]的值,为1,则指向下一个描述符地址

RX DMA描述符成员变量:

RDES0[31]置0:MAC将数据从RX FIFO传输到RX描述符中,拷贝完成之后将该位置0,告诉CPU可以接收数据

RDES0[14]置1:描述符中的第二个地址是下一个描述符地址【ST以太网驱动库是RDES0[14]置1】

RDES0[28:16]:如果RDES0[14]位置为1,则该字段无效

RDES0[31:0]:取决于RDES0[14],为1,则指向下一个描述符地址

STM32 ETH-DMA描述符(只用到了常规描述符而未用到增强型描述符):

ETH为发送接收申请内存:

发送:网络层下达pbuf->拷贝到TXFIFO->MAC->PHY(光电信号);

接收:外部->PHY->mac->RXFIFO->网络层

其中 ETH_TX_BUF_SIZE = ETH_MAX_PACKET_SIZE描述符最大长度为1524

STM32中提供的以太网驱动库使用的是链接结构:

描述符注意事项:

1.一个以太网数据包可以跨越一个或多个DMA描述符

2.一个DMA描述符只能用于一个以太网数据包

3.DMA描述符列表中的最后一个描述符指向第一个,形成链式结构

四、正点原子重点代码分析

总流程如下所示

img

1、LWIP初始化

img

//LWIP初始化(LWIP启动的时候使用)
//返回值:0,成功
//      1,内存错误
//      2,LAN8720初始化失败
//      3,网卡添加失败.
u8 lwip_comm_init(void)
{
    u8 retry=0;
    struct netif *Netif_Init_Flag;      //调用netif_add()函数时的返回值,用于判断网络初始化是否成功
    struct ip_addr ipaddr;              //ip地址
    struct ip_addr netmask;             //子网掩码
    struct ip_addr gw;                  //默认网关 
​
    if(ETH_Mem_Malloc())return 1;       //内存申请失败
    if(lwip_comm_mem_malloc())return 2; //内存申请失败
    lwip_comm_default_ip_set(&lwipdev); //设置默认IP等信
    while(LAN8720_Init())               //初始化LAN8720,如果失败的话就重试5次
    {
        retry++;
        if(retry>5) {retry=0;return 3;} //LAN8720初始化失败
    }
    lwip_init();                        //初始化LWIP内核
​
#if LWIP_DHCP       //使用动态IP
    ipaddr.addr = 0;
    netmask.addr = 0;
    gw.addr = 0;
#else               //使用静态IP
    IP4_ADDR(&ipaddr,lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]);
    IP4_ADDR(&netmask,lwipdev.netmask[0],lwipdev.netmask[1] ,lwipdev.netmask[2],lwipdev.netmask[3]);
    IP4_ADDR(&gw,lwipdev.gateway[0],lwipdev.gateway[1],lwipdev.gateway[2],lwipdev.gateway[3]);
    printf("网卡en的MAC地址为:................%d.%d.%d.%d.%d.%d\r\n",lwipdev.mac[0],lwipdev.mac[1],lwipdev.mac[2],lwipdev.mac[3],lwipdev.mac[4],lwipdev.mac[5]);
    printf("静态IP地址........................%d.%d.%d.%d\r\n",lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]);
    printf("子网掩码..........................%d.%d.%d.%d\r\n",lwipdev.netmask[0],lwipdev.netmask[1],lwipdev.netmask[2],lwipdev.netmask[3]);
    printf("默认网关..........................%d.%d.%d.%d\r\n",lwipdev.gateway[0],lwipdev.gateway[1],lwipdev.gateway[2],lwipdev.gateway[3]);
#endif
    Netif_Init_Flag=netif_add(&lwip_netif,&ipaddr,&netmask,&gw,NULL,&ethernetif_init,&ethernet_input);//向网卡列表中添加一个网口
    
#if LWIP_DHCP           //如果使用DHCP的话
    lwipdev.dhcpstatus=0;   //DHCP标记为0
    dhcp_start(&lwip_netif);    //开启DHCP服务
#endif
    
    if(Netif_Init_Flag==NULL)return 4;//网卡添加失败 
    else//网口添加成功后,设置netif为默认值,并且打开netif网口
    {
        netif_set_default(&lwip_netif); //设置netif为默认网口
        netif_set_up(&lwip_netif);      //打开netif网口
    }
    return 0;//操作OK.
}   

(1)ETH_Mem_Malloc()

为描述符及缓冲区申请内存,除了这种用算法实现的内存申请函数可以申请内存之外,ST官方给出的例程是使用简单的使用数组来实现申请内存。

(2)判断是否开启DHCP(动态IP)

未开启则采用静态IP:申请远端IP地址、网卡MAC地址、本地IP地址、子网掩码、默认网关

(3)以太网环境配置

配置以太网环境、并且初始化RMII的IO(通过调用的HAL_ETH_Init函数,它会调用HAL_ETH_MspInit函数初始化相应的接口IO以及复位PHY芯片管脚)、复位PHY芯片(非常重要,不复位以太网通信不能成功

(4)初始化LwIP内核

它是LwIP内核源码自带的函数,初始化了一系列函数,如sys_init()、mem_init()、pbuf_init()、netif_init()。

2.添加虚拟网卡

LwIP是软件,如何管理真正的以太网硬件呢,比如网络接口有多种,如WIFI接口、以太网接口,怎么管理这些实际的网络接口,LwIP抽象了一个虚拟网卡来管理这些各种硬件网络接口。

(1)ethernetif_init:

网卡初始化,设置虚拟网卡参数,该函数在ethernetif.c文件中已经帮我们实现好了整体框架。它会调用low_level_init函数,该函数初始化发送和接收描述符,并开启ETH中断。

(2)err_t low_level_init:

初始化发送和接收描述符,并开启ETH中断。

(3)ethernetif_input:

以太网数据包输入,这里LwIP默认已经帮我们实现好了框架。开启虚拟网卡:通过low_level_input接收,再用netif结构体中的input字段(一个函数)来处理数据包

3.虚拟网卡控制块

img

4.发送流程

img

5.接收流程

接收有两种方式接收数据包,一种是查询式接收数据包,一种是中断方式接收数据包。

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2180036.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Springboot+Vue的视频点播系统设计与实现登录 (含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统中…

springboot工伤事故管理系统-计算机毕业设计源码04050

摘 要 工伤事故管理系统是为了提高企业对工伤事故的管理和处理能力而设计的。该系统主要利用现代技术手段构建一个全面、高效的工伤事故管理平台&#xff0c;帮助企业实现工伤事故的预防、记录、报告和分析。通过工伤事故管理系统&#xff0c;企业可以进行工伤事故的登记和记录…

pycharm汉化插件无法使用也无法卸载的解决方法

pycharm汉化插件无法使用也无法卸载的解决方法 本文目录&#xff1a; 一、故障描述 二、故障解决 零、时光宝盒 学习没有可能一帆风顺&#xff0c;我们都是在不断遇到的各种突发问题&#xff0c;不断努力解决的过程中成长。 前几天&#xff0c;我发现家里的网络晚上12点左右开…

VUE 开发——Node.js学习(一)

一、认识Node.js Node.js是一个跨平台JavaScript运行环境&#xff0c;使开发者可以搭建服务器端的JavaScript应用程序 使用Node.js编写服务器端程序——编写数据接口、前端工程化&#xff1b; Node.js环境没有BOM和DOM&#xff1b; Node.js安装&#xff1a;下载node-v16.19…

APO v0.5.0 发布:可视化配置告警规则;优化时间筛选器;支持自建的ClickHouse和VictoriaMetrics

APO 新版本 v0.5.0 正式发布&#xff01;本次更新主要包含以下内容&#xff1a; 新增页面配置告警规则和通知 在之前的版本中&#xff0c;APO 平台仅支持展示配置文件中的告警规则&#xff0c;若用户需要添加或调整这些规则&#xff0c;必须手动编辑配置文件。而在新版本中&a…

如何构建一个生产级的AI平台(4)?

书接上回&#xff0c;继续往下讲,本节会说一下复杂逻辑&#xff0c;可观测性和Pipeline 添加复杂逻辑和写入操作 到目前为止&#xff0c;我们讨论的应用程序具有相当简单的流程。 基础模型生成的输出大多返回给用户&#xff08;除非它们没有通过护栏&#xff09;。 但是&…

工业交换机的RMON

工业交换机在现代网络中扮演着至关重要的角色&#xff0c;它不仅负责数据的高效传输&#xff0c;还具备强大的监控和管理能力。其中&#xff0c;RMON&#xff08;远程监控&#xff09;功能使得交换机的性能得以进一步提升&#xff0c;成为网络管理的重要工具。RMON提供了一种先…

讯时语音网关按线路对接配置方法(mod_cti基于FreeSWITCH)

文章目录 前言问题场景 联系我们解决方案创建分机语音网关反向注册对接创建线路创建线路组配置外呼的线路组配置语音网关查看线路是否有问题 前言 问题场景 语音网关中配置了10条电话线&#xff0c;但是有些电话线不定时会出现不能使用的情况&#xff0c;这很影响呼叫的质量。…

java后端项目技术记录

后端使用技术记录 一、软件1. apifox&#xff0c;API管理软件问题 2. nginx前端服务器(1) 反向代理(2) 负载均衡 二、问题1. 使用spring全局异常处理器处理特定的异常2. 扩展springmvc的消息转换器&#xff08;对象和json数据的转换&#xff09;3. 路径参数的接收4. 实体构建器…

墙绘交易平台:SpringBoot框架的设计与实现

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本墙绘产品展示交易平台就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据…

在双十一必买的好物有哪些?2024双十一好物必入清单推荐

随着2024年双十一购物狂欢节的临近&#xff0c;消费者们正热切期待着这一年度盛事的到来。作为一年中最具影响力的购物节日之一&#xff0c;双十一不仅为消费者带来了前所未有的优惠力度&#xff0c;更是各大品牌展示新品、推广好物的绝佳时机&#xff0c;在众多商品中&#xf…

【Leecode 随笔】C语言版看了不后悔系列持续更新中。。。

文章目录 题目一&#xff1a;最长回文子串题目描述&#xff1a;示例输入与输出&#xff1a;题目分析&#xff1a;解题思路&#xff1a;示例代码&#xff1a;深入剖析&#xff1a; 题目二&#xff1a;合并K个有序链表题目描述&#xff1a;示例输入与输出&#xff1a;题目分析&am…

GaussDB关键技术原理:高弹性(六)

书接上文GaussDB关键技术原理&#xff1a;高弹性&#xff08;五&#xff09;从日志多流和事务相关方面对hashbucket扩容技术进行了解读&#xff0c;本篇将从扩容实践方面继续介绍GaussDB高弹性技术。 5 扩容实践 5.1 工具介绍 5.1.1 TPC-C TPC-C(全称Transaction Proces…

【使用resnet18训练自己的数据集】

1.背景及准备 书接上文【以图搜图代码实现】–犬类以图搜图示例 总结了一下可以优化的点&#xff0c;其中提到使用自己的数据集训练网络&#xff0c;而不是单纯使用预训练的模型&#xff0c;这不就来了&#xff01;&#xff01; 使用11类犬类微调resnet18网络模型&#xff1a…

如何实现一个优秀的散列表!

文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ 文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ 文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ 前言 假设现在有一篇很长的…

python-pptx 中 placeholder 和 shape 有什么区别?

在 python-pptx 库中&#xff0c;placeholder 和 shape 是两个核心概念。虽然它们看起来相似&#xff0c;但在功能和作用上存在显著的区别。为了更好地理解这两个概念&#xff0c;我们可以通过它们的定义、使用场景以及实际代码示例来剖析其差异。 Python-pptx 的官网链接&…

08_OpenCV文字图片绘制

import cv2 import numpy as npimg cv2.imread(image0.jpg,1) font cv2.FONT_HERSHEY_SIMPLEXcv2.rectangle(img,(500,400),(200,100),(0,255,0),20) # 1 dst 2 文字内容 3 坐标 4 5 字体大小 6 color 7 粗细 8 line type cv2.putText(img,flower,(200,50),font,1,(0,0,250)…

Kubernetes从零到精通(17-扩展-Operator模式)

目录 一、简介 二、核心概念 三、工作原理 四、Operator Framework SDK示例 1.准备工作 2. 定义MySQLCluster CRD 3. 自定义资源实例 4. 编写控制器逻辑 5. 部署Operator 6. 验证 一、简介 Kubernetes中的Operator模式是一种用于简化和自动化管理复杂应用程序(尤其是…

【最新华为OD机试E卷-支持在线评测】简单的自动曝光(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…

数字电路与逻辑设计-移位寄存器逻辑功能测试和应用

一、实验目的 l&#xff0e;验证移位寄存器的逻辑功能&#xff1b; 2&#xff0e;掌握集成电路4位双向移位寄存器的使用方法&#xff1b; 3&#xff0e;学会应用移位寄存器实现数据的串行、并行转换和构成环形计数器。 二、实验原理 l&#xff0e;移位寄存器的特点 寄存器…