第12课【DMA 直接数据访问】直接数据访问 效率 数据总线冲突 通道 仲裁器

news2025/1/18 21:18:51

目录

  • 简介
  • 功能框图
    • 请求
    • 通道
    • 仲裁器
  • 使用配置
    • 传输方向
    • 数据量
    • 传输模式
  • 实例分析
    • 存储器间传输
    • 存储器到外设

简介

DMA(Direct Memory Access 直接内存访问)指的是STM32中的一个外设。它可以在无需CPU介入的情况下,实现外设和存储器之间或存储器与存储器之间的数据传输,这里的存储器指的是SRAM或者是Flash。在进行一些大批量的,或者是周期性重复的数据转移工作时,通常都会使用到DMA,这使得CPU可以腾出时间完成其他更具意义的任务,从而提高处理效率,在这点上,DMA和GPU的存在意义类似,都是用于处理专门的需求或者数据而存在的

STM32的DMA的控制器包含了两个DMA:DMA1和DMA2,其中DMA1拥有7个通道(可以理解为数据传输通道),DMA2拥有5各通道。DMA2在大容量类型或互联网类型STM32产品上才会搭载

STM32上的DMA外设有以下特点:

  • 12个通道(DMA1有7个,DMA2有5个)都可独立配置
  • 低、中、高、最高四种通道优先级可选
  • SRAM,Flash,AHB/APB1/APB2总线上的基本所有外设都支持DMA

功能框图

STM32的DMA外设同其他外设一样,也是独立于Cortex内核的存在,其可以大致分为三部分:请求,通道,仲裁器,功能框图如下:

在这里插入图片描述

请求

其他外设如果需要使用DMA功能,需要向DMA发送请求,DMA收到请求后,会根据情况给发起请求的外设一个应答信号,只有当请求的外设收到应答信号时,才会启动DMA传输功能

通道

通道指代的是数据传输通道,DMA1有7条通道,DMA2有5条通道,12条通道都可以独立编程控制,并且每条通道对应了不同的外设,具体对应如下图:

  • DMA1通道对应外设:
    在这里插入图片描述
  • DMA2通道对应外设:
    在这里插入图片描述

可以看到,每个通道可以对应多个外设。但是同一时间,一个通道只能被一个外设使用,需要多个外设同时使用同一个通道时,开发者需要注意规划外设DMA通道时序,以确保通道带宽得到有效且正确的分配

DMA传输的实现机制以及拓展思考
DMA传输实际上还是需要同Cortex内核共享系统数据总线来实现的,这就意味着在DMA传输进行时,CPU依旧是需要等待的,既然需要等待那么如何提高访问效率呢。为此,STM开发者是这么设计的,当DMA外设和内核同时访问同一个设备时,DMA外设会暂停内核访问总线的若干个周期,同时总线总裁器执行循环调度,保证内核能至少获得总线一半的带宽,

仲裁器

类似于多个外设同时使用一个通道的场景,DMA传输在同一时刻只能对一个通道进行数据传输操作,当DMA控制器同时接收到来自多个通道的数据传输请求时,会通过优先级进行仲裁,优先级分为两种:软件优先级和硬件优先级

  • 软件优先级:可以通过DMA_CCR寄存器对单独某个通道进行优先级配置,分别有四种:低,中,高,最高。高优先级通道的数据传输请求会被优先处理
  • 硬件优先级:如果某两个通道的软件优先级配置一致,那么会根据通道固定的硬件优先级进行比较,硬件优先级数字越小,优先级越高

使用配置

DMA外设的数据传输配置,主要是需要对数据的元数据(即描述数据用的数据)进行配置:包括传输方向,数据量,传输模式

传输方向

DMA传输数据的方向分为三种:外设到存储器,存储器到外设,存储器到存储器。三种方向主要通过以下寄存器中的位来配置:

  • DMA_CCR寄存器的DIR位:配置DMA数据的传输方向,DIR位置1时,从存储器读取数据,写入到外设,即存储器->外设;DIR位清0时,从外设读取数据,写入到存储器中,即外设->存储器;当使用存储器到存储器模式时,还需要将寄存器中的MEM2MEM位置1。
  • DMA_CPARx(x = 1~7)寄存器:配置外设的地址
  • DMA_CMARx(x = 1…7)寄存器:配置存储器的地址

具体举例三种情况:

  • 外设到存储器:例如通过DMA外设将串口外设的数据传输到SRAM中,首先要配置DMA_CPARx
    寄存器中的外设地址,也就是串口外设的数据寄存器地址,之后再配置DMA_CMARx
    寄存器中的存储器地址,即代码中的临时缓存变量地址,临时变量会存储于SRAM中,最后将DMA_CCR寄存器中的DIR位清0,表示传输方向为:外设->存储器
  • 存储器到外设:与上一个例子类似,只不过传输方向需要改为存储器->外设,需要将DMA_CCR寄存器中的DIR位置1
  • 存储器到存储器:存储器到存储器同以上两个例子有些许不同,例如将Flash的数据传输到SRAM(Flash中的数据只读),那么可以将Flash的访问地址当作外设地址,配置到DMA_CPARx寄存器中;将临时变量的地址当作存储器地址,配置到DMA_CMARx寄存器中;而此模式下传输方向仅支持配置为Flash到SRAM,DMA_CCR寄存器的DIR位无需进行配置;同时需要将DMA_CCR寄存器中的MEM2MEM位置

数据量

数据量的配置包括了,数据量大小,单个数据的宽度,以及数据指针增量模式。主要通过以下寄存器中的位来配置:

  • DMA_CNDTRx(x = 1…7)寄存器:用于显示剩余待传输的数据的量。最小值为0,此时无论如何都不会发生数据传输,最大值为65535(无符号32位寄存器),最多一次能传输65536Bytes的数据。每传输1Byte数据,此寄存器会自减1。如果此寄存器的值自减到0,那么会根据是否有配置重载数据,进行寄存器值重新装载
  • DMA_CCRx(x = 1…7)寄存器的PSIZE位[1:0]/MSIZE位[1:0]:用于配置外设/存储器数据宽度。PSIZE位[1:0]配置外设数据宽度,MSIZE位[1:0]配置存储器数据宽度,可以是8/16/32位。但是要确保两者的数据宽度是一致的,才能进行数据传输
  • DMA_CCRx(x = 1…7)寄存器的PINC位/MINC位:用于配置数据传输时的数据指针增量模式,外设的地址指针由DMA_CCRx的PINC位配置,PINC位置1时,每完成一次数据传输,外设的数据指针会自增1,PINC位清0时,每完成一次数据传输,外设的数据指针保持不变,存储器的地址指针由MINC位配置,配置方法和PINC位类似。是否需要启用指针增量模式,由开发者来决定

传输模式

传输模式分为两种:单次传输和循环传输。顾名思义,单次传输进行一次传输,而循环传输会一直不间断的进行单次传输,每轮单次传输完成后,都会重新按照初始配置重新进行传输。传输模式由DMA_CCRx(x = 1…7)寄存器的CIRC位控制,CIRC位置1时,执行循环传输操作,CIRC位清0时,执行单次传输操作

对于两种传输的传输状态,包括传输过半,传输完成,传输出错都有相应的标志位去查询,同时也可以启用中断,通过中断去对特定指定状态执行对应操作

实例分析

以下内容基于STM32F103VET野火指南者开发板,分别实现两个功能:

  • (存储器间传输)通过DMA将Flash数据复制到SRAM中,对比两份数据,查看DMA传输是否成功
  • (存储器到外设)通过DMA将SRAM数据复制到串口外设的数据寄存器中,并循环发送到PC端,查看是否准确发送。同时主程序中运行LED闪烁实验,以验证DMA传输不影响CPU进行其他活动

会使用到开发板的LED灯模块以及USB串口模块(实际上是USART模块+CH340G芯片),原理图分别如下:

  • LED灯模块:
    在这里插入图片描述
  • CH340G芯片:
    在这里插入图片描述

首先,需要解析标准库提供的DMA初始化结构体,以及相关操作函数:

/** 
  * @brief  DMA Init structure definition
  */

typedef struct
{
  uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Channelx. */

  uint32_t DMA_MemoryBaseAddr;     /*!< Specifies the memory base address for DMAy Channelx. */

  uint32_t DMA_DIR;                /*!< Specifies if the peripheral is the source or destination.
                                        This parameter can be a value of @ref DMA_data_transfer_direction */

  uint32_t DMA_BufferSize;         /*!< Specifies the buffer size, in data unit, of the specified Channel. 
                                        The data unit is equal to the configuration set in DMA_PeripheralDataSize
                                        or DMA_MemoryDataSize members depending in the transfer direction. */

  uint32_t DMA_PeripheralInc;      /*!< Specifies whether the Peripheral address register is incremented or not.
                                        This parameter can be a value of @ref DMA_peripheral_incremented_mode */

  uint32_t DMA_MemoryInc;          /*!< Specifies whether the memory address register is incremented or not.
                                        This parameter can be a value of @ref DMA_memory_incremented_mode */

  uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data width.
                                        This parameter can be a value of @ref DMA_peripheral_data_size */

  uint32_t DMA_MemoryDataSize;     /*!< Specifies the Memory data width.
                                        This parameter can be a value of @ref DMA_memory_data_size */

  uint32_t DMA_Mode;               /*!< Specifies the operation mode of the DMAy Channelx.
                                        This parameter can be a value of @ref DMA_circular_normal_mode.
                                        @note: The circular buffer mode cannot be used if the memory-to-memory
                                              data transfer is configured on the selected Channel */

  uint32_t DMA_Priority;           /*!< Specifies the software priority for the DMAy Channelx.
                                        This parameter can be a value of @ref DMA_priority_level */

  uint32_t DMA_M2M;                /*!< Specifies if the DMAy Channelx will be used in memory-to-memory transfer.
                                        This parameter can be a value of @ref DMA_memory_to_memory */
}DMA_InitTypeDef;

其中结构体成员的含义分别如下:

  • DMA_PeripheralBaseAddr:外设地址
  • DMA_MemoryBaseAddr:存储器地址
  • DMA_DIR:数据传输方向。可以是外设->存储器,也可以是存储器->外设
  • DMA_BufferSize:传输数据量的大小。最小为0Byte,最大为65536Bytes
  • DMA_PeripheralInc:外设地址的增量模式。由开发者选择是否使用
  • DMA_MemoryInc:存储器地址的增量模式。由开发者选择是否使用
  • DMA_PeripheralDataSize:外设地址可以获取到的单次传输的数据大小。可以是8/16/32bits
  • DMA_MemoryDataSize:存储器地址可以获取到的单次传输的数据大小。可以是8/16/32bits
  • DMA_Mode:传输模式。分为单次传输和循环传输
  • DMA_Priority:通道优先级。分为低、中、高、最高四种
  • DMA_M2M:是否开启存储器到存储器模式。只有使用存储器间传输时会开启

存储器间传输

此功能的实现思路为:

  • 初始化Flash中的源数据,以及SRAM中的目标数据
  • 初始化LED灯用GPIO口
  • 初始化DMA传输参数
  • 启动DMA传输
  • 对比源数据与目标数据,将结果通过LED灯颜色展示出来

分别建立DMA相关板级支持文件bsp_dma.h,bsp_dma.c,内容分别如下:

  • bsp_dma.h:
#ifndef __BSP_DMA_H__
#define __BSP_DMA_H__

#include <stdint.h>

#define DMA_CHANNEL DMA1_Channel1
#define DMA_CLK     RCC_AHBPeriph_DMA1
#define DMA_FLAG_TC DMA1_FLAG_TC1

#define DMA_BUFFER_SIZE 32

extern const uint32_t aSRC_Const_Buffer[DMA_BUFFER_SIZE];
extern uint32_t aDST_Buffer[DMA_BUFFER_SIZE];

void DMA_Config(void);
uint8_t BufferCompare(const uint32_t *pSRCBuffer, uint32_t *pDSTBuffer, uint16_t BufferLength);

#endif
  • bsp_dma.c:
#include "bsp_dma.h"
#include "stm32f10x.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_rcc.h"
#include <stdint.h>

// The "const" keyword for a global variable will cause it to be storged in ROM(Flash)
const uint32_t aSRC_Const_Buffer[DMA_BUFFER_SIZE] = 
{
    0x01020304, 0x05060708, 0x090A0B0C, 0x0D0E0F10, 
    0x11120304, 0x05160718, 0x090A1B0C, 0x0D0E0F10, 
    0x21220304, 0x05260728, 0x090A2B0C, 0x0D0E0F20, 
    0x31320304, 0x05360738, 0x090A3B0C, 0x0D0E0F30, 
    0x41420304, 0x05460748, 0x090A4B0C, 0x0D0E0F40, 
    0x51520304, 0x05560758, 0x090A5B0C, 0x0D0E0F50, 
    0x61620304, 0x05660768, 0x090A6B0C, 0x0D0E0F60, 
    0x71720304, 0x05760778, 0x090A7B0C, 0x0D0E0F70
};

// Without the "const" keyword, a global variable will be storged in SRAM
uint32_t aDST_Buffer[DMA_BUFFER_SIZE];

void DMA_Config(void)
{
    // DMA
    DMA_InitTypeDef DMA_InitStructure;
    // DMA Clk enable
    RCC_AHBPeriphClockCmd(DMA_CLK, ENABLE);
    // DMA param config
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) aSRC_Const_Buffer;
    DMA_InitStructure.DMA_MemoryBaseAddr     = (uint32_t) aDST_Buffer;
    DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize         = DMA_BUFFER_SIZE;
    DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Enable;
    DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority           = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M                = DMA_M2M_Enable; // Enable M2M
    DMA_Init(DMA_CHANNEL, &DMA_InitStructure);
    // DMA enable
    DMA_Cmd(DMA_CHANNEL, ENABLE);
}

uint8_t BufferCompare(const uint32_t *pSRCBuffer, uint32_t *pDSTBuffer, uint16_t BufferLength)
{
    for (int i=0; i<BufferLength; ++i)
    {
        if (*(pSRCBuffer+i) == *(pDSTBuffer+i))
        {
            continue;
        }
        else 
        {
            return 1;
        }
    }

    return 0;
}

通过板级支持包代码实现需求:

#include "userapp.h"
#include "bsp_dma.h"
#include "bsp_clkconfig.h"
#include "bsp_led.h"
#include "stm32f10x.h"
#include "stm32f10x_dma.h"
#include <stdint.h>

int userapp(void)
{
    LED_GPIO_Init();

    Delay(3000000);    

    LED_PURPLE;

    DMA_Config();

	// Wait until DMA transfer complete 
    while (DMA_GetFlagStatus(DMA_FLAG_TC) == RESET);

    Delay(3000000);    

	// Compare buffer and show result by different LED color
    if (BufferCompare(aSRC_Const_Buffer, aDST_Buffer, BUFFER_SIZE) == 0)
    {
        LED_GREEN;
    }
    else 
    {
        LED_RED;
    }

    while (1)
    {
    }
}

存储器到外设

此功能的实现思路为和存储器间的样例没有很大不同,但是要注意以下几点:

  • 需要初始化串口用GPIO口以及串口模块
  • 不需要开启DMA传输的M2M模式
  • 将Flash当作外设来处理
  • 需要额外配置USART的DMA控制发送功能,此功能仅DMA 通道4支持

分别建立DMA相关板级支持文件bsp_dma_uart.h,bsp_dma_uart.c,内容分别如下:

  • bsp_dma_uart.h:
#ifndef __BSP_DMA_UART_H__
#define __BSP_DMA_UART_H__

#include "stm32f10x_usart.h"

#define UART_DR_ADDR         (USART1_BASE + 0x04)

// DMA
#define UART_DMA_CLK              RCC_AHBPeriph_DMA1
#define UART_DMA_CHANNEL          DMA1_Channel4 // channel 4 support only
#define UART_DMA_BUFFER_SIZE      64

extern uint8_t aSRC_Buffer[UART_DMA_BUFFER_SIZE];

void UART_DMA_Config(void);

#endif
  • bsp_dma_uart.c:
#include "bsp_dma_uart.h"
#include "bsp_uart.h"
#include "stm32f10x.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_usart.h"
#include <stdint.h>

uint8_t aSRC_Buffer[UART_DMA_BUFFER_SIZE] = "HeLLo WoRld !!! This is a demo of DMA/UART\n";

void UART_DMA_Config(void)
{
    // DMA
    DMA_InitTypeDef DMA_InitStructure;
    // DMA Clk enable
    RCC_AHBPeriphClockCmd(UART_DMA_CLK, ENABLE);
    // DMA param config
    DMA_InitStructure.DMA_PeripheralBaseAddr = UART_DR_ADDR;
    DMA_InitStructure.DMA_MemoryBaseAddr     = (u32)aSRC_Buffer;
    DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize         = UART_DMA_BUFFER_SIZE;
    DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode               = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority           = DMA_Priority_Medium;
    DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;
    DMA_Init(UART_DMA_CHANNEL, &DMA_InitStructure);
    // DMA enable
    DMA_Cmd (UART_DMA_CHANNEL,ENABLE);
    
    // DMA UART TX enable
    USART_DMACmd(USARTx, USART_DMAReq_Tx, ENABLE);
}

通过板级支持包代码实现需求:

#include "userapp.h"
#include "bsp_clkconfig.h"
#include "bsp_uart.h"
#include "bsp_dma_uart.h"
#include "bsp_led.h"
#include "stm32f10x.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_usart.h"
#include <stdint.h>

int userapp(void)
{
    LED_GPIO_Init();

    LED_PURPLE;

    USART_Config();

    Delay(5000000);

    UART_DMA_Config();

    while (1)
    {
        LED_GREEN;
        Delay(5000000);
        LED_OFF;
        Delay(5000000);
    }
}

示例代码已上传Github:Sinuxtm32

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

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

相关文章

毕业季,给大家用python画一个飞机吧~预祝大家一帆风顺

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 今天我们主要用到turtle这个模块&#xff0c;它是python自带的&#xff0c; 所以无需安装&#xff0c;我们直接导入使用就好了~命令如下&#xff1a; import turtle那这个模块有什么作用呢&#xff1f; 它是python中…

LeetCode刷题(ACM模式)-02链表

参考引用&#xff1a;代码随想录 注&#xff1a;每道 LeetCode 题目都使用 ACM 代码模式&#xff0c;可直接在本地运行&#xff0c;蓝色字体为题目超链接 0. 链表理论基础 0.1 链表定义 链表是一种通过指针串联在一起的线性结构&#xff0c;每一个节点由两部分组成&#xff1a…

01背包问题-递推公式的自我理解与LeetCode 416. 分割等和子集

学算法好痛苦&#xff0c;完全是对我智力的一次次折磨&#xff0c;看了好多博客&#xff0c;对二维dp数组的理解都是直接搬了代码随想录&#xff0c;搬了随想录又没详细解释&#xff0c;大家都是一眼看懂的吗&#xff0c;好吧&#xff08;&#xff09; LeetCode 416. 分割等和子…

华侨大学主题模版

华侨大学主题模版 适用于 课程作业、实验报告、项目策划、毕业论文、毕设答辩... 这是一个非官方项目&#xff0c;仅供个人学习研究。 &#x1f680; 指南 &#x1f4d6; 仓库简介 该仓库提供了一系列适用于课程作业、实验报告、项目策划、毕业论文、毕设答辩等场景的华侨大…

API接口对电商平台有怎样的帮助?如何获取API接口?

API&#xff08;Application Programming Interface&#xff09;接口对电商平台有很多帮助&#xff0c;下面列举几点&#xff1a; 1.提高效率 API接口可以让电商平台的不同模块之间进行快速的数据交互&#xff0c;帮助平台实现更高效的业务处理。比如&#xff0c;在订单管理和…

牛客网学习之倒置字符串(详解fgets函数,如何读取含有空格的字符串)

题目要求&#xff1a; 过程分析&#xff1a;&#xff08;大致思路&#xff09; 具体代码&#xff1a; #include <stdio.h> #include <string.h> /*逆序字符串*/ void reverse(char* begin,char* end) {while (begin < end){char temp *begin;*begin *end;*en…

程序员的出路是什么?

做为一个程序员&#xff0c;工作了一定时间后&#xff0c;一定会有一个想法&#xff0c;那就是程序员能干多久&#xff0c;未来的发展方向是什么&#xff0c;更专业一点的说法是&#xff0c;职业规划到底是什么。 说实话&#xff0c; 我也仔细考虑过这个问题&#xff0c;偶尔也…

基于 HTTP Range 实现文件分片并发下载!

目录 前言 基础下载功能 进阶下载功能 单片下载 多片下载 浏览器发送预检&#xff08;preflight&#xff09;请求 express 不支持多段 range multipart/** 搭配 boundary** 分片下载功能 “只读的” ArrayBuffer 对象 DataView 子类 Uint8Array 操作二进制数据 Bl…

不愧是腾讯出来的,太厉害了...

前段时间公司缺人&#xff0c;也面了许多测试&#xff0c;一开始瞄准的就是中级水准&#xff0c;当然也没指望能来大牛&#xff0c;提供的薪资在15-20k这个范围&#xff0c;来面试的人有很多&#xff0c;但是平均水平真的让人很失望。看了简历很多上面都是写有4年工作经验&…

Go对Json的支持[encoding/json]

数据类型中转json的函数 基本数据转json Marshal使用以下与类型相关的默认编码: 布尔值编码为JSON布尔值。 浮点数、整数和数字值编码为JSON数字。 字符串值编码为JSON字符串&#xff0c;强制为有效的UTF-8; 用Unicode替换符文替换无效字节。 这样JSON就可以安全地嵌入到HTML …

2023年5月软考考试真题及答案汇总

2023上半年软考考试在5月27日-5月28日举行&#xff0c;为大家整理了各科目的考试真题及答案&#xff0c;可用于估分。&#xff08;会持续更新哦&#xff09; ​ 2023年上半年系统集成项目管理工程师上午题 1、在&#xff08; &#xff09;领域&#xff0c;我国还远未达到世界…

【数据结构】---几分钟简单几步学会手撕链式二叉树(中)

文章目录 前言&#x1f31f;一、二叉树链式结构的实现&#x1f30f;1.1 二叉树叶子节点个数&#x1f4ab;代码&#xff1a;&#x1f4ab;流程图&#xff1a; &#x1f30f;1.2 二叉树的高度&#x1f4ab;第一种写法(不支持)&#xff1a;&#x1f4d2;代码&#xff1a;&#x1f…

TCP协议的三次握手和四次挥手

完整的TCP内容&#xff0c;请参考RFC 9293 TCP协议为应用提供可靠的、有序的的字节流服务。TCP是面向连接的&#xff0c;提供了全双工的通信。TCP使用端口号来识别应用程序服务并在主机之间复用不同的流。 TCP header格式 TCP header也像IP header一样&#xff0c;在header中…

【Kafka】超详细介绍

文章目录 概念部署方案磁盘网络CPUpartition的数量 命令查看版本找kafka和zookeeper的ip/porttopic创建 topic查看get topic 列表get topic 详情 修改topic修改分区级别参数(如增加partition) 删除topic设置消息大小上限 生产查看生产生产消息 查看消费server 查看 offset查看积…

车载电子之汽车HUD技术

一、什么是HUD技术 HUD&#xff08;head up display抬头显示器&#xff09;是将重要信息显示在挡风玻璃上的一种显示系统&#xff0c;基本原理是&#xff1a;投影仪发出的光信息&#xff0c;经过一系列的折射、反射等投影到挡风玻璃上&#xff0c;人眼就能看到投射在上面的信息…

springboot+vue广场舞团系统(java项目源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的广场团舞系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风歌&a…

Jmeter接口测试-websocket测试

壹 Jmeter接口测试-websocket测试 测试之前的准备工作,需要websocket插件 方式一: 去github下载: https://github.com/maciejzaleski/JMeter-WebSocketSampler/wiki/Dependencies jetty-http-9.1.2.v20140210.jarjetty-io-9.1.2.v20140210.jarjetty-util-9.1.2.v20140210…

华为OD机试真题 Java 实现【云短信平台优惠活动】【2023Q1 200分】,附详细解题思路

一、题目描述 某云短信厂商&#xff0c;为庆祝国庆&#xff0c;推出充值优惠活动。 现在给出客户预算&#xff0c;和优惠售价序列&#xff0c;求最多可获得的短信总条数。 二、输入描述 第一行客户预算M&#xff0c;其中 0<M<1000000。 第二行给出售价表&#xff0c…

华为OD机试真题B卷 Java 实现【小朋友排队】

一、题目描述 小明今年升学到了小学1年级&#xff0c;来到新班级后&#xff0c;发现其他小朋友身高参差不齐&#xff0c;然后就想基于每个小朋友和自己的身高差&#xff0c;对他们进行排序&#xff0c;请帮他实现排序。 二、输入描述 第一行为正整数h和n。 0 < h < 2…

算法基础学习笔记——⑤离散化\区间和并

✨博主&#xff1a;命运之光 ✨专栏&#xff1a;算法基础学习 目录 ✨简述 特指整数离散化 &#x1f353;离散化模板&#xff1a; ✨区间和并 &#x1f353;区间和并模板&#xff1a; 前言&#xff1a;算法学习笔记记录日常分享&#xff0c;需要的看哈O(∩_∩)O&#xff0…