当前位置: 首页 > article >正文

嵌入式系统中的Board Support Package (BSP)详解:以Xilinx Zynq为例

嵌入式系统中的Board Support Package (BSP)详解:以Xilinx Zynq为例

引言

在嵌入式系统开发中,硬件与软件的无缝集成至关重要。Board Support Package (BSP) 作为连接硬件和操作系统的桥梁,在这一过程中扮演着核心角色。本文将深入探讨BSP的概念、组成部分及其在Xilinx Zynq平台上的应用,特别聚焦设备树和硬件抽象层(HAL)这两个关键组件,帮助您理解BSP如何简化嵌入式系统开发并提高开发效率。

BSP的基本概念

什么是BSP?

Board Support Package (BSP)是一组软件组件的集合,它为特定硬件平台提供基础支持,使操作系统能够在该硬件上正常运行。BSP封装了硬件细节,提供标准化接口,允许上层软件(如操作系统和应用程序)与底层硬件交互而无需了解硬件的具体实现。

在嵌入式系统软件层次结构中,BSP的位置如下:
在这里插入图片描述

应用软件↓
操作系统/中间件↓
Board Support Package (BSP)↓
硬件平台

BSP的组成部分

一个典型的BSP通常包含以下核心组件:

  1. 引导加载程序(Bootloader)

    • 初始化关键硬件组件
    • 加载操作系统内核
    • 例如:FSBL (First Stage Boot Loader)、U-Boot等
  2. 设备驱动程序

    • 为各种硬件外设提供操作接口
    • 包括UART、I2C、SPI、GPIO、以太网等驱动
    • 允许操作系统控制和使用这些设备
  3. 硬件初始化代码

    • 配置时钟、电源管理和内存控制器
    • 设置中断控制器
    • 初始化关键系统组件
  4. 硬件抽象层(HAL)

    • 提供硬件寄存器的抽象访问接口
    • 简化应用程序对硬件的操作
    • 提高代码可移植性
  5. 设备树

    • 描述硬件配置的数据结构
    • 定义外设、内存映射和中断
    • 配置内核如何与硬件交互
  6. 内存映射表

    • 定义硬件寄存器和内存区域的地址映射
    • 配置内存控制器和缓存
    • 设置内存保护单元
  7. 配置文件

    • 系统参数定义
    • 编译和链接选项
    • 硬件配置信息

BSP的功能与职责

BSP在嵌入式系统中执行以下关键功能:

  1. 硬件抽象:隐藏硬件细节,提供统一接口
  2. 设备支持:通过驱动程序支持各种硬件外设
  3. 启动与初始化:确保系统正确启动和初始化
  4. 中断管理:处理和分发硬件中断
  5. 电源管理:控制系统电源状态
  6. 内存管理:配置和管理系统内存
  7. 调试支持:提供调试接口和工具

Xilinx Zynq平台概述

在深入Zynq BSP之前,先了解一下Xilinx Zynq平台的基本架构。

Zynq架构特点

Xilinx Zynq是一种异构系统级芯片(SoC),集成了处理系统(PS)和可编程逻辑(PL):

  1. 处理系统(PS)

    • 包含ARM Cortex-A9双核处理器(Zynq-7000系列)或Cortex-A53四核处理器(Zynq UltraScale+系列)
    • 集成内存控制器、USB、以太网、UART等标准外设
    • 提供高性能通用计算能力
  2. 可编程逻辑(PL)

    • 基于FPGA技术的可编程硬件
    • 可实现定制硬件加速器和接口
    • 提供灵活的硬件定制能力
  3. PS-PL接口

    • 通过AXI接口连接处理系统和可编程逻辑
    • 支持高速数据传输
    • 实现软硬件协同设计

这种异构架构使Zynq平台非常适合需要高性能处理和硬件加速的嵌入式应用。

Zynq启动流程

Zynq平台的启动过程涉及多个阶段,BSP在其中扮演关键角色:

  1. BootROM

    • 芯片内置的只读程序
    • 执行初始启动配置
    • 加载FSBL
  2. FSBL (First Stage Boot Loader)

    • 初始化关键硬件(处理器、DDR、时钟等)
    • 加载FPGA比特流(如果有)
    • 加载第二阶段引导程序(通常是U-Boot)
  3. U-Boot

    • 初始化更多硬件设备
    • 提供命令行界面
    • 加载操作系统内核和设备树
  4. 操作系统

    • 接管系统控制
    • 初始化驱动程序
    • 启动应用程序

Xilinx Zynq的BSP详解

Zynq BSP的类型

Xilinx为Zynq平台提供了两种主要的BSP实现方式:

  1. 独立式BSP (Standalone BSP)

    • 用于裸机应用或实时操作系统
    • 不依赖复杂的操作系统
    • 提供基本的硬件抽象层
    • 适合资源受限或实时要求高的应用
  2. 基于操作系统的BSP

    • 支持Linux、FreeRTOS等操作系统
    • 提供完整的驱动程序和服务
    • 包含设备树和内核配置
    • 适合复杂应用和网络功能

Zynq Standalone BSP的组成

以Xilinx Vitis/SDK创建的Standalone BSP为例,其主要组件包括:

  1. 处理器初始化代码

    • 初始化ARM处理器
    • 配置MMU、缓存和异常向量
    • 设置栈和堆
  2. 外设驱动库

    • 提供访问UART、I2C、SPI等外设的API
    • 支持中断和DMA操作
    • 包含PS-PL接口驱动
  3. 系统库

    • 提供标准C库函数
    • 包含数学函数和字符串处理
    • 支持内存分配和管理
  4. 启动代码

    • 处理器复位后的入口点
    • 执行硬件初始化
    • 调用main函数
  5. 链接脚本

    • 定义内存布局
    • 指定代码和数据段位置
    • 配置堆栈大小

Zynq Linux BSP的组成

使用PetaLinux工具创建的Linux BSP主要包括:

  1. FSBL

    • 初始化基本硬件
    • 加载FPGA比特流
    • 加载U-Boot
  2. U-Boot

    • 第二阶段引导加载程序
    • 提供环境变量和命令行界面
    • 加载Linux内核和设备树
  3. Linux内核

    • 定制的Linux内核
    • 包含Zynq特定驱动程序
    • 支持PS和PL部分集成
  4. 设备树

    • 描述硬件配置的数据结构
    • 定义外设、内存映射和中断
    • 配置内核如何与硬件交互
  5. 根文件系统

    • 基本的Linux文件系统
    • 包含系统工具和库
    • 可选的应用程序和服务

BSP创建与定制

使用Xilinx工具创建BSP

Xilinx提供了多种工具来创建和定制BSP:

  1. 使用Vitis/SDK创建Standalone BSP

    a. 创建硬件平台:

    • 使用Vivado设计硬件系统
    • 导出硬件描述到Vitis

    b. 创建BSP项目:

    • 在Vitis中创建新的应用项目
    • 选择"创建新的平台"选项
    • 导入硬件描述文件
    • 选择处理器(如PS7_cortexa9_0)

    c. 配置BSP设置:

    • 选择操作系统(如"standalone")
    • 配置BSP选项(如stdout设备、堆栈大小等)
    • 选择需要的库和驱动程序

    d. 生成BSP:

    • Vitis自动生成BSP文件
    • 生成的BSP包含所有必要的驱动和库
  2. 使用PetaLinux创建Linux BSP

    a. 创建PetaLinux项目:

    petalinux-create --type project --template zynq --name my_project
    

    b. 导入硬件描述:

    cd my_project
    petalinux-config --get-hw-description=/path/to/hardware
    

    c. 配置Linux内核:

    petalinux-config -c kernel
    

    d. 配置根文件系统:

    petalinux-config -c rootfs
    

    e. 构建BSP:

    petalinux-build
    

    f. 打包BSP映像:

    petalinux-package --boot --format BIN --fsbl images/linux/zynq_fsbl.elf --u-boot
    

深入理解设备树(Device Tree)

设备树的基本概念

设备树是一种描述硬件配置的数据结构,它采用树状结构组织,包含节点和属性。在嵌入式Linux系统中,设备树已成为描述非x86架构硬件的标准方法,取代了早期的硬编码方式。

设备树的主要目的是将硬件描述与内核代码分离,使同一个内核镜像可以支持多种硬件配置,只需更换设备树文件即可。

设备树文件格式

设备树有三种主要文件格式:

  1. DTS (Device Tree Source)

    • 人类可读的文本格式
    • 包含节点、属性和值
    • 使用类似C语言的语法
  2. DTB (Device Tree Blob)

    • 编译后的二进制格式
    • 由内核直接解析
    • 通常由bootloader加载并传递给内核
  3. DTSI (Device Tree Source Include)

    • 包含公共定义的源文件
    • 可被多个DTS文件包含
    • 用于代码复用

设备树在Zynq中的应用

在Zynq平台上,设备树负责描述:

  1. 处理系统(PS)外设

    • 描述ARM核心、缓存、MMU等
    • 定义内存控制器和DDR配置
    • 配置UART、I2C、SPI、以太网等外设
  2. 可编程逻辑(PL)组件

    • 描述用户创建的IP核
    • 定义AXI接口和中断映射
    • 配置PL时钟和电源域
  3. PS-PL接口

    • 定义AXI互连配置
    • 映射PL中断到PS中断控制器
    • 配置DMA通道

设备树示例(Zynq相关部分)

以下是Zynq平台设备树的简化示例:

/ {compatible = "xlnx,zynq-7000";cpus {#address-cells = <1>;#size-cells = <0>;cpu@0 {compatible = "arm,cortex-a9";device_type = "cpu";reg = <0>;clocks = <&clkc 3>;};cpu@1 {compatible = "arm,cortex-a9";device_type = "cpu";reg = <1>;clocks = <&clkc 3>;};};amba: amba {compatible = "simple-bus";#address-cells = <1>;#size-cells = <1>;uart0: serial@e0000000 {compatible = "xlnx,xuartps";reg = <0xe0000000 0x1000>;interrupts = <0 27 4>;clocks = <&clkc 23>, <&clkc 40>;clock-names = "uart_clk", "pclk";};/* 其他PS外设节点... */};/* PL部分自定义IP */my_custom_ip: my_custom_ip@43c00000 {compatible = "vendor,my-custom-ip";reg = <0x43c00000 0x10000>;interrupts = <0 29 4>;};
};

在这个例子中:

  • 顶层节点定义了整个系统
  • cpus节点描述了双核Cortex-A9处理器
  • amba节点包含了AMBA总线上的PS外设
  • uart0节点描述了UART外设的基地址、中断号和时钟源
  • my_custom_ip节点描述了PL中的自定义IP核

设备树与内核驱动的关系

设备树与内核驱动程序之间存在密切的关系:

  1. 设备-驱动匹配

    • 内核使用compatible属性匹配设备和驱动
    • 驱动程序通过设备树获取硬件配置信息
    • 无需修改驱动代码即可支持不同硬件配置
  2. 资源获取

    • 驱动程序从设备树获取资源信息(地址、中断等)
    • 使用标准API访问这些资源
    • 例如:of_iomap()of_irq_get()
  3. 设备属性配置

    • 通过设备树配置驱动行为
    • 定义设备特定参数
    • 支持运行时选项

硬件抽象层(HAL)详解

HAL的概念与目的

硬件抽象层(Hardware Abstraction Layer, HAL)是一种软件层,它隐藏了底层硬件的具体细节,提供标准化的API,使上层软件能够以一致的方式访问不同的硬件平台。

HAL的主要目的是:

  • 提高代码可移植性
  • 简化应用程序开发
  • 隐藏硬件复杂性
  • 标准化硬件访问接口

HAL的层次结构

HAL通常分为多个层次:

  1. 底层HAL

    • 直接与硬件寄存器交互
    • 提供基本的读写操作
    • 实现最低级别的硬件控制
  2. 中间层HAL

    • 提供设备级别的抽象
    • 实现通用功能(如中断管理)
    • 处理硬件特定的初始化和配置
  3. 上层HAL

    • 提供面向应用的API
    • 实现高级功能(如DMA传输)
    • 隐藏平台特定的细节

Zynq Standalone BSP中的HAL实现

在Zynq的Standalone BSP中,HAL主要包括:

  1. 低级硬件访问函数
    • 寄存器读写操作
    • 内存屏障和同步原语
    • 例如:Xil_In32()Xil_Out32()
// 读取32位寄存器
static inline u32 Xil_In32(u32 Addr) {return *(volatile u32 *) Addr;
}// 写入32位寄存器
static inline void Xil_Out32(u32 Addr, u32 Value) {*(volatile u32 *) Addr = Value;
}
  1. 外设驱动API
    • 设备初始化和配置
    • 数据传输和处理
    • 中断管理
// GPIO设备初始化
int XGpio_Initialize(XGpio *InstancePtr, u16 DeviceId) {XGpio_Config *ConfigPtr;// 查找设备配置ConfigPtr = XGpio_LookupConfig(DeviceId);if (ConfigPtr == NULL) {return XST_DEVICE_NOT_FOUND;}// 设置基地址和其他参数InstancePtr->BaseAddress = ConfigPtr->BaseAddress;// ...其他初始化代码...return XST_SUCCESS;
}// 设置GPIO方向
void XGpio_SetDataDirection(XGpio *InstancePtr, unsigned Channel, u32 DirectionMask) {// 计算寄存器地址u32 RegOffset = (Channel == 1) ? XGPIO_TRI_OFFSET : XGPIO_TRI2_OFFSET;// 写入方向寄存器Xil_Out32(InstancePtr->BaseAddress + RegOffset, DirectionMask);
}
  1. 系统服务
    • 异常和中断处理
    • 缓存和MMU管理
    • 定时器和延迟函数
// 启用ARM处理器中断
void Xil_ExceptionEnable(void) {// 修改CPSR寄存器,启用中断asm volatile ("mrs r0, cpsr");asm volatile ("bic r0, r0, #0x80");asm volatile ("msr cpsr_c, r0");
}

Zynq Linux BSP中的HAL实现

在Linux BSP中,HAL的实现更加复杂,它通过内核的多层抽象实现:

  1. 内核硬件抽象

    • 体系结构特定代码(arch/arm/)
    • 通用设备模型和驱动框架
    • 资源管理和分配
  2. 设备驱动框架

    • 平台设备和驱动模型
    • 总线抽象(如PCI、I2C、SPI)
    • 通用子系统(如GPIO、DMA、时钟)
  3. 用户空间接口

    • 设备文件(/dev/)
    • sysfs接口(/sys/)
    • ioctl调用

在Linux内核中,HAL的一个重要部分是设备驱动模型,它提供了统一的框架来管理设备和驱动程序。例如,Zynq的UART驱动:

static struct platform_driver cdns_uart_platform_driver = {.probe = cdns_uart_probe,.remove = cdns_uart_remove,.driver = {.name = CDNS_UART_DRIVER_NAME,.of_match_table = cdns_uart_of_match,.pm = &cdns_uart_pm_ops,},
};static int cdns_uart_probe(struct platform_device *pdev)
{struct resource *res;struct uart_port *port;int irq;// 从设备树获取资源res = platform_get_resource(pdev, IORESOURCE_MEM, 0);if (!res)return -ENODEV;// 获取中断号irq = platform_get_irq(pdev, 0);if (irq < 0)return irq;// 分配端口结构port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);if (!port)return -ENOMEM;// 设置端口参数port->membase = devm_ioremap_resource(&pdev->dev, res);port->irq = irq;// ...其他初始化代码...// 注册UART端口return uart_add_one_port(&cdns_uart_uart_driver, port);
}

BSP、设备树和HAL的关系

BSP、设备树和HAL这三个概念紧密相关,共同构成了嵌入式系统的软件基础。

他们之间的概念的关系,我们在下一篇博客中讨论

相关文章:

嵌入式系统中的Board Support Package (BSP)详解:以Xilinx Zynq为例

嵌入式系统中的Board Support Package (BSP)详解&#xff1a;以Xilinx Zynq为例 引言 在嵌入式系统开发中&#xff0c;硬件与软件的无缝集成至关重要。Board Support Package (BSP) 作为连接硬件和操作系统的桥梁&#xff0c;在这一过程中扮演着核心角色。本文将深入探讨BSP的…...

Spring Boot 定时任务以及异步任务的实现

一、定时任务 在 Spring Boot 中&#xff0c;实现定时任务非常简单&#xff0c;主要通过 Scheduled 注解和 TaskScheduler 接口来实现。以下是实现定时任务的详细步骤和方法&#xff1a; 启用定时任务支持 在 Spring Boot 应用中&#xff0c;首先需要启用定时任务支持。可以通…...

Vue 生命周期详解:从创建到销毁的全过程

Vue.js 是一个流行的前端框架&#xff0c;它通过组件化的方式帮助开发者构建用户界面。在 Vue 中&#xff0c;每个组件实例都有其生命周期&#xff0c;从创建、挂载、更新到销毁&#xff0c;Vue 提供了一系列的生命周期钩子函数&#xff0c;允许我们在组件的不同阶段执行自定义…...

【ASMbits--常用算术运算指令】

ASMbits--常用算术运算指令 1 基本运算算术指令--最基础1.1 加法和减法1.2 移位操作1.3 乘法 2 practice2.1 编写invert(int n)2.2 编写judge_odd(int n)2.3 计算绝对值abs(int n)2.4 add(int n1, int n2)函数2.4 shift寄存器2.5 sihft ath right2.6 shift left 在ARMv7汇编中&…...

计算机基础:二进制基础12,十进制数转换为十六进制

专栏导航 本节文章分别属于《Win32 学习笔记》和《MFC 学习笔记》两个专栏&#xff0c;故划分为两个专栏导航。读者可以自行选择前往哪个专栏。 &#xff08;一&#xff09;WIn32 专栏导航 上一篇&#xff1a;计算机基础&#xff1a;二进制基础11&#xff0c;十六进制的位基…...

SpringCloud系列教程(十四):Sentinel持久化

Sentinel之前已经搭建和应用成功了&#xff0c;但是它有一个很大的缺点就是官方没有提供持久化的方案&#xff0c;从项目源码上看感觉这款工具也没有完成的太好&#xff0c;所以需要我们去对它进行二次开发。要补充的功能大概如下&#xff1a; 1、将Sentinel接入nacos中&#…...

Slider,InputField,Scroll View,Scrollbar及Layout组件

Slider组件 Fill Rect:填充滑动条选中区域的背景图部分 Handle Rect:滑动条的球 Direction:滑动条的滑动方向 Min Value:起始位置的数值&#xff08;浮点数&#xff09; Max Value:结束位置的数值&#xff08;浮点数&#xff09; Whole Numbers:必须为整数&#xff08;布尔…...

ollama注册自定义模型(GGUF格式)

文章目录 ollama注册自定义模型&#xff08;GGUF格式&#xff09;下载模型注册模型(GGUF格式) ollama注册自定义模型&#xff08;GGUF格式&#xff09; 需要全程开启ollama nohup ollama serve > ollama.log 2>&1 &需要注意&#xff0c;尽管手动下载的GGUF格式模…...

【算法】 区间合并(附蓝桥杯真题) python

步骤 1.先将所有区间按左端点排序 2.从前往后扫一遍&#xff0c;维护当前正在合并的区间[st, ed] 3.依次检查每个区间[l, r]&#xff0c; 若 l > ed,将[st, ed]加入 ans , 更新st l,ed r 若 l < ed &#xff0c;更新ed max(ed, r) 时间复杂度 O(nlogn) 模板 https:/…...

关于重构分析查询界面的思考(未完)

业务系统里&#xff0c;查询界面很常见&#xff0c;数据分析场景需求普遍而迫切&#xff0c;而新的技术也在不断出现&#xff0c;很有必要重构分析查询界面。 查询筛选 为了尽可能从数据中发现&#xff0c;需要尽可能地将查询条件添加进来&#xff0c;可这样&#xff0c;查询…...

机器人技能列表

一、机器人制作基础入门 &#xff08;一&#xff09;机器人概述 1.机器人的定义与分类 2.机器人的发展历程与现状 3.机器人在各领域的应用案例 &#xff08;二&#xff09;必备工具与材料 4.常用电子工具介绍&#xff08;万用表、电烙铁等&#xff09; 5.机械加工工具&…...

五大基础算法——分治算法

分治算法 是一种通过将问题分解为多个规模较小的子问题&#xff0c;递归解决子问题&#xff0c;然后将子问题的解合并为原问题解的算法思想。它通常包含三个步骤&#xff1a;分解&#xff08;Divide&#xff09;、解决&#xff08;Conquer&#xff09; 和 合并&#xff08;Comb…...

HarmonyOS NEXT 声明式UI语法学习笔记-创建自定义组件

基础语法概述 ArkTS的基本组成 装饰器&#xff1a;用于装饰类、结构、方法以及变量&#xff0c;并赋予其特殊含义。如上图都是装饰器&#xff0c;Component表示自定义组件&#xff0c;Entry表示表示自定义组件的入口组件&#xff0c;State表示组件中的状态变量&#xff0c;当状…...

补充二分LIS

B3637 最长上升子序列 题目描述 这是一个简单的动规板子题。 给出一个由 n ( n ≤ 5000 ) n(n\le 5000) n(n≤5000) 个不超过 1 0 6 10^6 106 的正整数组成的序列。请输出这个序列的最长上升子序列的长度。 最长上升子序列是指&#xff0c;从原序列中按顺序取出一些数字排…...

用户模块——握手验证

1. 引言 在现代 Web 应用中&#xff0c;WebSocket 以其全双工通信、低延迟、减少 HTTP 开销等优势&#xff0c;被广泛应用于即时通讯、在线游戏、实时数据推送等场景。然而&#xff0c;在涉及用户认证时&#xff0c;WebSocket 存在一个常见问题——每次刷新页面都会重新建立 We…...

97.HarmonyOS NEXT跑马灯组件教程:基础概念与架构设计

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; HarmonyOS NEXT跑马灯组件教程&#xff1a;基础概念与架构设计 1. 跑马灯组件概述 跑马灯&#xff08;Marquee&#xff09;是一种常见的UI组件&a…...

81.HarmonyOS NEXT 状态管理与响应式编程:@Observed深度解析

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; HarmonyOS NEXT 状态管理与响应式编程&#xff1a;Observed深度解析 文章目录 HarmonyOS NEXT 状态管理与响应式编程&#xff1a;Observed深度解析…...

【Agent】OpenManus-Agent架构详细分析

各组件详细设计见&#xff1a; BaseAgent&#xff1a;BaseAgentReActAgent&#xff1a;ReActAgentToolCallAgent&#xff1a;ToolCallAgent具体Agent实现&#xff1a;具体AgentMemory数据结构&#xff1a;Memory 1. 智能体层次结构 OpenManus 采用了一个多层次的智能体继承结…...

股指期货有卖不出去的时候吗?

在股指期货的交易世界里&#xff0c;很多人都有这样的疑问&#xff1a;股指期货会不会有卖不出去的时候呢&#xff1f;答案是会的&#xff0c;下面咱们就来详细唠唠为啥会出现这种情况。 市场极端行情下难以卖出 1.跌停限制&#xff1a;股指期货和股票一样&#xff0c;也有涨…...

前端Html5 Canvas面试题及参考答案

目录 Canvas 元素的默认尺寸是多少?如何正确设置其宽高以避免图像拉伸? 如何获取 Canvas 的 2D 上下文对象?3D 上下文支持哪些技术? canvas.width 与 canvas.style.width 的区别是什么? Canvas 支持的图像格式有哪些?如何将 Canvas 转换为 Base64 图片? Canvas 中如…...

【ES6】03-Set + Map

本文介绍两种集合 set map 的操作和方法。 目录 1. Set 1.1 set基本使用 1.2 add 1.3 delete 1.4 has 1.5 size 1.6 set转换为数组 1.7 拓展运算符 1.8 for...of 1.9 forEach 1.10 set给数组去重 2. Map 2.1 创建map集合 2.2 set添加元素 2.3 delete删除元素 …...

Java缓存String(字符串常量池)、Integer (-128 到 127 )

对问题的解释 1. “字符串常量池存储的是string对象的直接引用&#xff0c;而不是直接存放的对象&#xff0c;是一张string table” 的含义 这句话可以从以下几个方面理解&#xff1a; (1) 字符串常量池的存储内容 直接引用&#xff1a;字符串常量池中存储的是指向实际 Stri…...

消息队列的特性与使用场景:Kafka、ActiveMQ、RabbitMQ与RocketMQ的深度剖析

在分布式系统和微服务架构中&#xff0c;消息队列是实现服务间通信和解耦的核心组件。Kafka、ActiveMQ、RabbitMQ和RocketMQ是当前最受欢迎的消息队列解决方案&#xff0c;它们各自具有独特的特性和适用场景。本文将从特性和使用场景两个维度进行对比分析&#xff0c;帮助读者更…...

开发、科研、日常办公工具汇总(自用,持续更新)

主要记录汇总一下自己平常会用到的网站工具&#xff0c;方便查阅。 update&#xff1a;2025/2/11&#xff08;开发网站补一下&#xff09; update&#xff1a;2025/2/21&#xff08;补充一些AI工具&#xff0c;刚好在做AI视频相关工作&#xff09; update&#xff1a;2025/3/7&…...

解决VueI18n使用浏览器插件翻译后,切换国际化失效的问题

问题复现 在使用Vue-i18n对页面进行国际化的时候&#xff0c;使用浏览器翻译插件&#xff08;如腾讯翻译&#xff09;后&#xff0c;切换国际化语言&#xff0c;随后当我们关闭浏览器翻译插件后&#xff0c;再次切换国际化语言&#xff0c;原来被翻译的文字无法正确切换 出现…...

HTML5 drag API实现列表拖拽排序

拖拽API&#xff08;Drag and Drop API&#xff09;是HTML5提供的一组功能&#xff0c;使得在网页上实现拖放操作变得更加简单和强大。这个API允许开发者为网页元素添加拖拽功能&#xff0c;用户可以通过鼠标将元素拖动并放置到指定的目标区域。 事件类型 dragstart&#xff1…...

改变一生的思维模型【11】升维

升维思维模型&#xff1a;突破认知局限的破局法则 一、定义与核心逻辑 升维思维是通过增加分析维度&#xff0c;将问题投射到更高认知层次寻找解决方案的思考方式。其本质是跳出原有竞争维度&#xff0c;在更广阔的空间重构游戏规则。核心逻辑在于&#xff1a;当低维战场陷入…...

【动手学深度学习】#2线性神经网络

主要参考学习资料&#xff1a; 《动手学深度学习》阿斯顿张 等 著 【动手学深度学习 PyTorch版】哔哩哔哩跟李牧学AI 目录 2.1 线性回归2.1.1 线性回归的基本元素线性模型损失函数解析解随机梯度下降 2.1.3 最大似然估计 2.2 线性回归从零开始实现2.2.1 生成数据集2.2.2 读取数…...

计算机网络——NAT

一、什么是NAT&#xff1f; NAT&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09; 是一种将 私有IP地址 与 公有IP地址 相互映射的技术&#xff0c;主要用于解决IPv4地址不足的问题。它像一名“翻译官”&#xff0c;在数据包经过路由器或防火墙时…...

Stable Deffusion--常见模型插件详解

1.Checkpoint大模型 Checkpoint 是生成图像的基础模型&#xff0c;决定了整体画风如动漫、写实、机甲等。它是必选项&#xff0c;所有图像生成必须基于一个主模型。文件体积较大通常 1.5GB 以上&#xff0c;格式为 .ckpt 或 .safetensors。 存放位置为&#xff1a;\models\Sta…...