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

ZYNQ笔记(十三):双核 AMP 通信实验

版本:Vivado2020.2(Vitis)

ZYNQ 裸机双核 AMP 实验:

        CPU0 接收串口的数据,并写入 OCM 中,然后利用软件产生中断触发 CPU1;CPU1 接收到中断后,根据从 OCM 中读出的数据控制呼吸灯的频率,并在控制结束后触发 CPU0 中断,实现了双核 CPU 通信的功能。

目录

一、介绍

(1)双核 AMP 通信

(2)ZYNQ启动流程(裸机)

二、硬件设计

三、软件设计

(1)新建 CPU0 应用工程

(2)分配 CPU0 DDR 空间

(3)新建 CPU1 应用工程

(4)分配 CPU0 DDR 空间

(5)代码部分

(6)下载

四、效果


一、介绍

        Zynq-7000 SoC 集成了 双核 ARM Cortex-A9 MPCore,采用对称多处理(SMP)架构,同时支持非对称多处理(AMP)模式,适用于嵌入式高性能计算和实时控制场景。

(1)双核 AMP 通信

        直接附上正点原子开发指南的内容切片:

          — — — — — — — — — — — — — 分割线 — — — — — — — — — — — — 

(2)ZYNQ启动流程(裸机)

        上面介绍有提到了一些专有名词(如BootROM、FSBL、OCM),这里连带介绍一下 ZYQN(Xilinx Zynq-7000 SoC) 裸机开发时的启动流程,主要分为以下几个阶段:

1. Boot ROM

  • 硬件自动执行:上电或复位后,芯片首先运行片内ROM中的固化代码(Boot ROM)。

  • 启动模式检测:根据硬件配置(如模式引脚设置)确定启动源(如QSPI Flash、SD卡、NAND Flash、JTAG等)。

  • 加载FSBL:从启动设备中读取 FSBL(First Stage Boot Loader)到芯片的 OCM(On-Chip Memory)或 DDR 中(需预先配置DDR,本次例程配置了所以程序基于 DDR 运行)。

2. FSBL(First Stage Boot Loader)

  • 功能

    • 初始化必要外设(如DDR控制器、时钟、PLL)。

    • 从Flash或SD卡中加载用户程序(裸机代码或第二阶段引导程序)。

    • 可配置 PL(Programmable Logic)部分(可选,需加载比特流文件)。

  • 生成方式:通过 Xilinx SDK 或 Vitis 工具链生成(基于用户硬件设计)。

  • 执行位置:通常在 OCM 中运行。

3. 用户程序(裸机代码)

  • 加载与执行:FSBL将用户编写的裸机程序(ELF文件)加载到DDR或OCM中,并跳转到其入口地址。执行程序。

二、硬件设计

        (1)本实验是用软件产生中断(SGI)的方式来控制两个 CPU 访问共享内存的过程:

        首先需要处理器向共享内存中写入一个数据,本实验选择 CPU0 往共享内存中写入数据。当 CPU0 写入成功后就发送一条软中断指令去触发 CPU1 去读取共享内存中的数据。

        当 CPU1 读取到共享内存的数据后需要通过 M_AXI_GP0 接口的 AXI4-Lite 总线将数据发送到 PL 端呼吸灯的 IP 核, 呼吸灯的IP核根据PS发过来的数据对呼吸频率进行相应的配置,然后 CPU1 发送一条软中断指令触发 CPU0 继续往共享内存中写入数据。

        到此便实现了两个 CPU 通过共享内存进行数据交互的功能,同时为了对IP核进行控制以及方便观察数据流的走向,用 UART 接收控制命令以及打印 Debug 信息。

        (2)关于自定义 LED 呼吸灯 IP 核的设计与使用这里不再赘述,跟之前笔记的例程操作步骤一致,详细参考:ZYNQ笔记(六):自定义IP核-LED呼吸灯

        (3)最后整体 bd 设计部分如图所示:设计检查、Generate Output Products、 Create HDL Wrapper、管脚约束、Gnerate Bitstream、Export Hardware(包含比特流文件)、启动Vitis

        注意 LED 呼吸灯的 IP 核要手动添加 LED 管脚并与开发板的 LED 对应管脚绑定。

三、软件设计

(1)新建 CPU0 应用工程

        新建工程名 “cpu0_uart” ,系统工程名“AMP_2core_system”,通过cpu0实现串口通信,主要是从uart接收控制命令。如图所示,同时处理器选择ps7_cortexa9_0(默认也是cpu0).

(2)分配 CPU0 DDR 空间

        单核应用工程,默认将DDR空间全部分配给cpu0,这里用到了双核所以需要进行分配,就直接将DDR分二部分,一部分给cpu0,另一部分给cpu1(具体怎么大小分配都行),如图所示:

        红框标注的地方左侧为基地址,右侧为存储空间大小(单位字节),存储空间大小将默认的完整空间大小 0x1FF00000 (十进制 535,822,336;535,822,336/1024/1024 = 511MByte),修改为为 0x0FF00000(十进制 267,386,880;267,386,880/1024/1024 = 255MByte)。修改完成后,按下“Ctrl”+ “S”保存。

        另外图中的 ps7_ram_0 和 ps_ram_1 为 OCM 共享内存的基地址和存储空间大小。后面双核通信就是通过这访问这两块共享存储区域实现的,后面软件设计也会用到其的基地址以进行访问(本例程任选一个即可,后面的设计选用的是 ps_ram_0 基地址0x0)。

(3)新建 CPU1 应用工程

        在创建 CPU1 应用工程之前,需要新建基于 CPU1 的板级支持包(BSP)。双击 platform.spr,打开 system_wrapper 设置界面,如下图所示:

        之后依次对硬件平台工程(system_wrapper)右击选择 Clean Project 和 Build Project。

        接下来创建 CPU1 的应用工程,右键系统工程 AMP_2core_system 选择“Add Application Project”,从而在系统工程下添加一个新的应用工程,工程名命名为 cpu1_led,处理器选择 ps7_cortexa9_1, 如图所示:

(4)分配 CPU0 DDR 空间

        同样需要为 cpu2 分配 DDR 空间,两个核的DDR空间不能有重合,负责程序运行时会出现同时访问导致程序异常,所以这里要对起始地址和大小同时进行修改,如图所示:

        起始地址 = CPU0 的 DDR 起始地址 + 其分配大小 = 0x10000 + 0x0FF00000 = 0x10000000 分配大小 ≤  DDR 完整大小 - CPU0 的 DDR 分配大小 = 0x1FF00000(由开发板DDR大小决定)- 0x0FF00000 = 0x10000000 。修改完成后,按下“Ctrl”+“S”保存。

(5)代码部分

        新建 cpu0_uart 应用工程源文件“mian_0.c”,编写代码:

#include "xparameters.h"
#include "xscugic.h"
#include "xil_printf.h"
#include "xil_exception.h"
#include "xil_mmu.h"
#include "stdio.h"//============================宏定义===============================//
#define SHARE_BASE           	0x0		                     //共享OCM首地址(根据lscript.ld设置)
#define CPU1_COPY_ADDR       	0xfffffff0                   //存放CPU1应用起始地址的地址(参考ug585手册)
#define CPU1_START_ADDR      	0x10000000                   //CPU1应用起始地址(给cpu1分配的DDR起始地址)#define INTC_DEVICE_ID	     	XPAR_SCUGIC_SINGLE_DEVICE_ID //GIC中断控制器ID
#define CPU1_ID              	XSCUGIC_SPI_CPU1_MASK        //CPU1 ID
#define SOFT_INTR_ID_CPU0 	 	0                            //软件中断号 0 ,范围0~15
#define SOFT_INTR_ID_CPU1    	1                            //软件中断号 1 ,范围0~15//"SEV"指令唤醒CPU1并跳转至相应的程序
#define sev()                __asm__("sev")               //C语言内嵌汇编写法 send event指令//===========================函数声明==============================//
void start_cpu1();
void cpu0_intr_init(XScuGic *intc_ptr);
void soft_intr_handler(void *CallbackRef);//===========================全局变量==============================//
XScuGic Intc;                    //中断控制器驱动程序实例
int rec_freq_flag = 0;           //接收到呼吸灯频率设置的标志
int speed;                       //频率速度档位(0~7)//=========================CPU0 main函数===========================//
int main()
{//S=b1 TEX=b100 AP=b11, Domain=b1111, C=b0, B=b0Xil_SetTlbAttributes(SHARE_BASE,0x14de2);    //禁用OCM的Cache属性//S=b1 TEX=b100 AP=b11, Domain=b1111, C=b0, B=b0Xil_SetTlbAttributes(CPU1_COPY_ADDR,0x14de2);//禁用0xfffffff0的Cache属性//启动CPU1(固化程序时需使用)//start_cpu1();//CPU0中断初始化cpu0_intr_init(&Intc);while(1){if(rec_freq_flag == 0){xil_printf("CPU0: Input 0~7 to change breath LED frequency \r\n");xil_printf("\r\n");//输入0~7指令scanf("%d",&speed);if(speed >= 0 && speed <= 7){xil_printf("CPU0: Input Command %d \r\n",speed);//向共享的地址中写入输入的数据Xil_Out8(SHARE_BASE,speed);//CPU0软件触发CPU1中断XScuGic_SoftwareIntr(&Intc, SOFT_INTR_ID_CPU1, CPU1_ID);rec_freq_flag = 1;}else{xil_printf("CPU0: Command Error, out of range 0~7 \r\n");}}}return 0 ;
}//====================启动CPU1,用于固化程序=======================//
// 如果只是通过 JTAG 模式下载程序,可以不编写这个启动函数,这个函数仅在固化程序的时候起作用。
void start_cpu1()
{//向 CPU1_COPY_ADDR(0Xffffffff0)地址写入 CPU1 的访问内存基地址Xil_Out32(CPU1_COPY_ADDR, CPU1_START_ADDR);dmb();  //等待内存写入完成(同步)sev();  //通过"SEV"指令唤醒CPU1并跳转至相应的程序
}//=========================中断处理函数===========================//
void soft_intr_handler(void *CallbackRef)
{xil_printf("CPU0: Received Soft Interrupt from CPU1 (set finish) \r\n");rec_freq_flag = 0;
}//========================CPU0中断初始化==========================//
void cpu0_intr_init(XScuGic *intc_ptr)
{//初始化中断控制器XScuGic_Config *intc_cfg_ptr;intc_cfg_ptr = XScuGic_LookupConfig(INTC_DEVICE_ID);XScuGic_CfgInitialize(intc_ptr, intc_cfg_ptr,intc_cfg_ptr->CpuBaseAddress);//设置中断异常处理功能Xil_ExceptionInit();Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler, intc_ptr);//使能处理器中断Xil_ExceptionEnable();//关联中断函数XScuGic_Connect(intc_ptr, SOFT_INTR_ID_CPU0,(Xil_ExceptionHandler)soft_intr_handler, (void *)intc_ptr);//使能中断XScuGic_Enable(intc_ptr, SOFT_INTR_ID_CPU0); //CPU0软件中断
}

        新建 cpu1_led 应用工程源文件“mian_1.c”,编写代码:

#include "xparameters.h"
#include "xscugic.h"
#include "xil_printf.h"
#include "xil_exception.h"
#include "xil_mmu.h"
#include "stdio.h"
#include "breath_led_ip.h"//============================宏定义===============================//
#define SHARE_BASE  	     	0x0      		             //共享OCM首地址(根据lscript.ld设置)#define INTC_DEVICE_ID	     	XPAR_SCUGIC_SINGLE_DEVICE_ID //GIC中断控制器ID
#define CPU0_ID              	XSCUGIC_SPI_CPU0_MASK        //CPU0 ID
#define SOFT_INTR_ID_CPU0 		0                            //软件中断号 0 ,范围0~15
#define SOFT_INTR_ID_CPU1 		1                            //软件中断号 1 ,范围0~15#define LED_IP_BASEADDR     	XPAR_BREATH_LED_IP_0_S0_AXI_BASEADDR //LED IP基地址
#define LED_EN					BREATH_LED_IP_S0_AXI_SLV_REG0_OFFSET //宏定义led_en  对应寄存器(slv_reg0)地址偏移量
#define SPEED_EN				BREATH_LED_IP_S0_AXI_SLV_REG1_OFFSET //宏定义speed_en对应寄存器(slv_reg1)地址偏移量
#define SPEED					BREATH_LED_IP_S0_AXI_SLV_REG2_OFFSET //宏定义speed   对应寄存器(slv_reg2)地址偏移量//===========================函数声明==============================//
void cpu1_intr_init(XScuGic *intc_ptr);
void soft_intr_handler(void *CallbackRef);//===========================全局变量==============================//
XScuGic Intc;               //中断控制器驱动程序实例
int soft_intr_flag = 0;     //软件中断的标志
int speed;                  //频率档位(0~7)//=========================CPU1 main函数===========================//
int main()
{//S=b1 TEX=b100 AP=b11, Domain=b1111, C=b0, B=b0Xil_SetTlbAttributes(SHARE_BASE,0x14de2);    //禁用OCM的Cache属性//CPU1中断初始化cpu1_intr_init(&Intc);//打开LED呼吸灯BREATH_LED_IP_mWriteReg(LED_IP_BASEADDR, LED_EN, 0x1);//使能LED呼吸灯频率设置BREATH_LED_IP_mWriteReg(LED_IP_BASEADDR, SPEED_EN, 0x1);while(1){if(soft_intr_flag){speed = Xil_In8(SHARE_BASE);     //从共享OCM中读出数据xil_printf("CUP1: Received Command is %d \r\n",speed) ;//设置LED呼吸灯频率BREATH_LED_IP_mWriteReg(LED_IP_BASEADDR, SPEED, speed);//CPU1软件触发CPU0中断XScuGic_SoftwareIntr(&Intc,SOFT_INTR_ID_CPU0,CPU0_ID);soft_intr_flag = 0;}}return 0 ;
}//=========================中断处理函数===========================//
void soft_intr_handler(void *CallbackRef)
{xil_printf("CPU1: Received Soft Interrupt from CPU0 (command ready) \r\n") ;soft_intr_flag = 1;
}//=========================CPU1中断初始化=========================//
void cpu1_intr_init(XScuGic *intc_ptr)
{//初始化中断控制器XScuGic_Config *intc_cfg_ptr;intc_cfg_ptr = XScuGic_LookupConfig(INTC_DEVICE_ID);XScuGic_CfgInitialize(intc_ptr, intc_cfg_ptr,intc_cfg_ptr->CpuBaseAddress);//设置中断异常处理功能Xil_ExceptionInit();Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler, intc_ptr);//使能处理器中断Xil_ExceptionEnable();//关联中断函数XScuGic_Connect(intc_ptr, SOFT_INTR_ID_CPU1,(Xil_ExceptionHandler)soft_intr_handler, (void *)intc_ptr);//使能中断XScuGic_Enable(intc_ptr, SOFT_INTR_ID_CPU1); //CPU1软件中断
}

(6)下载

        下载时需要将两个应用工程以及FPGA的比特流文件全部勾选下载。操作如图所示:

        选中两个核的应用工程:

        选中同时下载FPGA波特率文件(这个选项一般是默认勾选了):

四、效果

        1.下载后CPU0打印输入指令的提示信息,同时LED灯已经开始工作:

        2.第一次输入9(正确指令范围0~7),CPU0打印报错信息并重新提示输入指令。

        3.第二次输入1,CPU0打印出接受到的正确指令,接着CPU1打印接收到来自CPU0的中断的提示(表示CPU0已经将指令写入OCM),接着CPU0打印接收到来自CPU1的中断的提示(表示CPU1已经从OCM读取指令并设置LED灯速率),此时LED呼吸灯的速度发生对应变化(比初始的0档位闪烁的快一点),最后CPU0打印输入指令的提示信息(表示可以进行下一次设置操作)

        4.第三次输入7,流程同上,LED灯速率达到最大,闪烁最快。

        注意:

        本次例程用到scanf()(头文件 stidio.h)实现串口输入指令,这种方式可以在vitis串口终端上进行调试。但是如果要用一般的串口助手调试就不行,需要修改串口部分的软件设计,可以加上串口中断功能实现接收串口输入输出。参考笔记:ZYNQ笔记(八):UART 串口中断

        本次例程没有进行程序固化,所以没有使用到CPU0启动CPU1的函数,如果需要固化需要实现该函数,同时也许在硬件设计作配置,例如固化程序到 Flash 需要配置 QSPI Flash ,相关固化可操作参考笔记:ZYNQ笔记(七):程序固化(QSPI Flash)

相关文章:

ZYNQ笔记(十三):双核 AMP 通信实验

版本&#xff1a;Vivado2020.2&#xff08;Vitis&#xff09; ZYNQ 裸机双核 AMP 实验&#xff1a; CPU0 接收串口的数据&#xff0c;并写入 OCM 中&#xff0c;然后利用软件产生中断触发 CPU1&#xff1b;CPU1 接收到中断后&#xff0c;根据从 OCM 中读出的数据控制呼吸灯的频…...

黑马Java基础笔记-3

短路逻辑运算符与逻辑运算符 逻辑运算符 符号作用说明&逻辑与&#xff08;且&#xff09;并且&#xff0c;两边都为真&#xff0c;结果才是真|逻辑或或者&#xff0c;两边都为假&#xff0c;结果才是假^逻辑异或相同为 false&#xff0c;不同为 true!逻辑非取反 短路逻辑…...

4.23学习总结

虽然之前写过的相关dfs和bfs的题&#xff0c;但方法忘的差不多了&#xff0c;重写了一遍相关的算法题&#xff0c;今天完成了岛屿数量的算法题&#xff0c;我利用的是bfs的算法&#xff0c;遍历每个结点&#xff0c;如果是1就count,然后再bfs向四周遍历并标记已经走过 初步看了…...

ElasticSearch:高并发场景下如何保证读写一致性?

在Elasticsearch高并发场景下&#xff0c;可以通过以下多种方式来保证读写一致性&#xff1a; 等待主分片和副本分片都确认&#xff08;类似半同步机制&#xff09; 设置consistency参数&#xff1a;在写操作时&#xff0c;可以设置consistency参数来控制写操作的一致性级别。…...

Qt基础007(Tcp网络编程)

文章目录 QTcp服务器的关键流程QTtcp客户端的关键流程TCP协议Socket QTcp服务器的关键流程 工程建立&#xff0c;需要在.pro加入网络权限 创建一个基于 QTcpServer 的服务端涉及以下关键步骤&#xff1a; 创建并初始化 QTcpServer 实例&#xff1a; 实例化 QTcpServer 。 调…...

visio导出的图片过大导致latex格式转成pdf之后很不清楚

联想电脑解决方法 右键打开方式选择【照片】&#xff0c;然后选择调整图片大小&#xff0c;将像素的宽度和高度调低。...

leetcode刷题——判断对称二叉树(C语言版)

题目描述&#xff1a; 示例 1&#xff1a; 输入&#xff1a;root [6,7,7,8,9,9,8] 输出&#xff1a;true 解释&#xff1a;从图中可看出树是轴对称的。 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false 解释&#xff1a;从图中可看出最…...

STM32与i.MX6ULL内存与存储机制全解析:从微控制器到应用处理器的设计差异

最近做FreeRTos&#xff0c;以及前面设计的RVOS&#xff0c;这种RTOS级别的系统内存上的分布与CortexA系列里面的分布有相当大的区别&#xff0c;给我搞糊涂了。 目录 STM32&#xff08;Cortex-M系列&#xff09;的内存与存储机制 Flash存储内容RAM存储内容启动与运行时流程示例…...

经验分享-上传ios的ipa文件

.ipa格式的二进制文件&#xff0c;是打包后生成的文件&#xff0c;无论我们是放上去testflight测试还是正式上传到app store&#xff0c;都需要先上传到苹果开发者中心的app store connect上的构建版本上。 在app store connect上&#xff0c;上传构建版本的功能&#xff0c;它…...

Linux423 删除用户

查找 上面已查过&#xff1a;无法使用sudo 新开个终端试试 之前开了一个终端&#xff0c;按照deepseek排查 计划再开一个进程 开一个终端 后强制删除时显示&#xff1a;此事将被报告...

AI与Web3.0:技术融合

AI与Web3.0&#xff1a;技术融合 分享一下给大家一个从0开始学习ai 的网站。点击跳转到网站。 https://www.captainbed.cn/ccc 前言 随着互联网技术的飞速发展&#xff0c;Web3.0作为下一代互联网形态&#xff0c;正以前所未有的速度改变着我们的生活方式和工作模式。Web3.0强…...

Python爬虫第18节-动态渲染页面抓取之Splash使用上篇

目录 引言 一、Splash 的简介与安装 1.1 简介 1.2 安装 二、Splash 的使用 三、Splash Lua 脚本开发 3.1 脚本入口与返回值 3.2 异步处理 四、Splash 对象属性 4.1 args 4.2 js_enabled 4.3 resource_timeout 4.4 images_enabled 4.5 scroll…...

Linux进程状态及转换关系

目录 1、就绪态&#xff08;Ready&#xff09; 2、运行态&#xff08;Running&#xff09; 3、僵尸态&#xff08;Zombie&#xff09; 4、可中断睡眠态&#xff08;Interruptible Sleep&#xff09; 5、不可中断睡眠态&#xff08;Uninterruptible Sleep&#xff09; 6、…...

Java基础:认识注解,模拟junit框架

认识注解 自定义注解 注解的原理 元注解 解析注解 应该场景-配合反射做juint框架 public static void main(String[] args) {AnnotationDemo4 a new AnnotationDemo4();Class clazz AnnotationDemo4.class;Method[] methods clazz.getDeclaredMethods();for (Method method …...

chrony服务器

时间有什么作用&#xff1f;约定干什么事情&#xff0c;会出问题&#xff0c;双方约定会达成 一旦有一方的时间不准确&#xff0c;约定都会达不成 不联网&#xff0c;计算机运行一个月&#xff0c;你的计算机就会和标准的时间差一两分钟 通常情况下&#xff0c;硬件时间的运…...

Springboot——Redis的使用

在当今的软件开发领域&#xff0c;缓存技术是提升应用性能的关键手段之一。Redis 作为一款高性能的键值对存储数据库&#xff0c;凭借其出色的读写速度和丰富的数据结构&#xff0c;在缓存场景中得到了广泛应用。Spring Boot 作为一款简化 Spring 应用开发的框架&#xff0c;与…...

【EasyPan】removeFile2RecycleBatch方法及递归操作解析

【EasyPan】项目常见问题解答&#xff08;自用&持续更新中…&#xff09;汇总版 文件批量转移到回收站方法解析 一、方法总述 removeFile2RecycleBatch方法实现将用户选中的文件/目录及其子内容批量移入回收站的业务逻辑&#xff0c;主要特点&#xff1a; 递归处理&…...

AIGC的伦理困境:机器生成内容是否该被监管?

AIGC的伦理困境&#xff1a;机器生成内容是否该被监管&#xff1f; 在当今数字时代&#xff0c;人工智能&#xff08;AI&#xff09;技术的发展日新月异&#xff0c;其中生成式人工智能&#xff08;AIGC, AI-Generated Content&#xff09;作为一项前沿技术&#xff0c;正以前…...

缓存一致性

什么是缓存一致性&#xff1f; 当数据库和缓存之间的额数据内容保持同步或最终一致&#xff0c;称为缓存一致性 为什么缓存不一致会发生&#xff1f; 因为缓存和数据库是两个独立系统&#xff0c;它们的更新过程不是原子操作&#xff0c;就可能发生以下情况&#xff1a; //…...

【Java学习方法】终止循环的关键字

终止循环的关键字 一、break 作用&#xff1a;跳出最近的循环&#xff08;直接结束离break最近的那层循环&#xff09; 使用场景&#xff1a;一般搭配if条件判断&#xff0c;如果满足某个条件&#xff0c;就结束循环&#xff0c;&#xff08;场景&#xff1a;常见于暴力枚举中…...

bert学习

BERT Google在2018年提出的​​预训练语言模型​​&#xff0c;通过双向Transformer结构和大规模预训练。 核心特点 双向上下文 与传统模型&#xff08;如LSTM或单向Transformer&#xff09;不同&#xff0c;BERT通过同时考虑单词的​​左右上下文​​来捕捉更丰富的语义信息。…...

读书笔记:淘宝十年产品与技术演进史

作者&#xff1a;大淘宝技术 原文地址&#xff1a;读书笔记&#xff1a;淘宝十年产品与技术演进史 本文是对《淘宝十年产品事》与《淘宝技术这十年》两本书的阅读笔记总结。通过回顾淘宝过去十年在产品、技术、架构、中间件及开放平台等方面的发展历程&#xff0c;展现了其从初…...

ROS 快速入门教程02

5. Node 节点 以智能手机为例&#xff0c;当我们使用智能手机的某个功能时&#xff0c;大多时候在使用手机的某个APP。同样当我们使用ROS的某个功能时&#xff0c;使用的是ROS的某一个或者某一些节点。 虽然每次我们只使用ROS的某一个或者某一些节点&#xff0c;但我们无法下…...

卷积神经网络常用结构

空间注意力机制(Spatial Attention)详解 空间注意力机制(Spatial Attention)详解 空间注意力机制是计算机视觉中的重要组件&#xff0c;它使网络能够选择性地关注特征图中的重要空间区域&#xff0c;同时抑制不相关区域的影响。 空间注意力机制结构图 空间注意力机制详细解析…...

neo4j中节点内的名称显示不全解决办法(如何让label在节点上自动换行)

因为节点过多而且想让节点中所有文字都显示出来而放大节点尺寸 从neo4j中导出png,再转成PDF来查看时&#xff0c;要看清节点里面的文字就得放大5倍才行 在网上看了很多让里面文字换行的办法都不行 然后找到一个比较靠谱的办法是在要显示的标签内加换行符 但是我的节点上显示的是…...

容器化-Docker-进阶

一、自定义镜像:从基础部署到镜像定制​ (一)Linux 与 Docker 原生部署 Nginx 对比​ Linux 原生部署 Nginx # 安装依赖 sudo apt-get update && sudo apt-get install -y build-essential openssl libpcre3-dev zlib1g-dev # 下载Nginx源码 wget http://nginx.org…...

Sqlserver 自增长id 置零或者设置固定值

在 SQL Server 中&#xff0c;如果需要重置一个表的自增长&#xff08;Identity&#xff09;列的当前值&#xff0c;通常有几种方法可以实现。但是&#xff0c;值得注意的是&#xff0c;直接将自增长列的值设置为0并不是一个推荐的做法&#xff0c;因为这会破坏自增长列的连续性…...

状态模式(State Pattern)详解

文章目录 一、状态模式简介1.1 什么是状态模式?1.2 为什么需要状态模式?1.3 状态模式的核心思想二、状态模式的结构2.1 UML类图2.2 各个组件的详细说明2.3 交互过程三、状态模式的实现步骤(以Java为例)步骤1:创建状态接口步骤2:实现具体状态类步骤3:创建上下文类步骤4:…...

Shopee五道质检系统重构东南亚跨境格局,2025年电商游戏规则悄然改写

在2024年的东南亚跨境电商市场&#xff0c;一场以“质量”为核心的深度变革正在上演。作为头部平台的Shopee率先出招&#xff0c;以一套“五道质检流程”打破行业旧格局&#xff0c;不仅有效遏制高企的退货率&#xff0c;更引发从卖家结构到政策制度的连锁反应。 这场质量革命…...

Unity-无限滚动列表实现Timer时间管理实现

今天我们来做一个UI里经常做的东西&#xff1a;无限滚动列表。 首先我们得写清楚实现的基本思路&#xff1a; 所谓的无限滚动当然不是真的无限滚动&#xff0c;我们只要把离开列表的框再丢到列表的后面就行&#xff0c;核心理念和对象池是类似的。 我们来一点一点实现&#x…...

Python高级爬虫之JS逆向+安卓逆向1.6节: 函数基础

目录 引言: 1.6.1 理解函数 1.6.2 定义函数 1.6.3 调用函数 1.6.4 位置实参 1.6.5 关键字实参 1.6.6 爬虫不要进接单群 引言: 大神薯条老师的高级爬虫+安卓逆向教程: 这套爬虫教程会系统讲解爬虫的初级,中级,高级知识,涵盖的内容包括基础爬虫,高并发爬虫的设计与…...

集结号海螺捕鱼组件搭建教程与源码结构详解(第四篇)

本篇将聚焦“冰封领域”场景构建与性能优化策略。本节适合有Unity经验的技术团队&#xff0c;对大型特效场景优化、C与Unity协同通信及资源动态加载有深入需求的开发者。 一、冰封领域场景设计理念 冰封领域是高难度玩法场景&#xff0c;常用于高段位玩家房间&#xff0c;场景…...

02.Python代码Pandas - Series全系列分享(使用.特点.说明.取值.函数)

02.Python代码Pandas - Series全系列分享(使用.特点.说明.取值.函数) 提示&#xff1a;帮帮志会陆续更新非常多的IT技术知识&#xff0c;希望分享的内容对您有用。本章分享的是pandas的使用语法。前后每一小节的内容是存在的有&#xff1a;学习and理解的关联性&#xff0c;希望…...

星火燎原:Spark技术如何重塑大数据处理格局

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业发展与社会进步的核心驱动力。面对海量且复杂的数据&#xff0c;传统的数据处理技术逐渐显得力不从心。而Apache Spark作为大数据领域的明星框架&#xff0c;凭借其卓越的性能与强大的功能&#xff0c;如同一束璀璨的星火…...

AI大模型和人脑的区别

为什么人脑没有幻觉&#xff0c;但是 AI 大语言模型有幻觉&#xff1f; 人脑和大型语言模型&#xff08;LLM&#xff09;在处理信息的方式上存在根本差异&#xff0c;这导致了幻觉现象主要出现在LLM中。LLM的幻觉是指模型生成了貌似合理但实际上错误或虚构的内容。 LLM的工作…...

第一章:基于Docker环境快速搭建LangChain框架的智能对话系统:从langchain环境搭建到多轮对话代码实现(大语言模型加载)

文章目录 前言一、langchain环境搭建1、docker容器搭建2、docker容器连接修改密码容器内容修改物理机修改 3、langchain安装 二、langchain构建简单智能对话示例1、基于deepseek的简单问答Demo2、langchain的invoke、stream与astream生成方法1、langchain的invoke、stream与ast…...

数据结构的学习(1)二分查找,利用二分查找找局部最小值,选择排序,冒泡排序,插入排序,位运算的基础知识

一、二分查找某个元素 &#xff08;1&#xff09;查找是否存在某个元素在数组中 思想&#xff1a; 1&#xff09;先看中间位置的值 2&#xff09;如果中间位置的值大于目标值说明目标值在整个数组中偏左的位置&#xff0c;改变右边界&#xff0c;即Right Mid - 1; 3&#xf…...

vue2+Vant 定制主题

参考文档&#xff1a;Vant主题定制-CSDV博客 vant提供了一套默认主题&#xff0c;若想完全替换主题是或者其他样式&#xff0c;则需要定制主题。 定制方法 1、main.js文件引入主题样式源文件 // 导入并安装 Vant 组件库 import Vant from vant // 切记&#xff1a;为了能够覆…...

【自然语言处理与大模型】大模型参数规模与部署配置调查2025第一季度

调查大模型参数规模与部署配置之间的关系。探讨如何在不同硬件和场景下优化大模型的部署。 一、 当前主流模型的参数规模对比 &#xff08;1&#xff09;当前主流模型有哪些 参考全球最大AI开源社区Hugging Face发布的榜单、上海AI实验室推出的开放评测体系OpenCompass和国内开…...

香港科技大学广州|先进材料学域博士招生宣讲会—南开大学专场

香港科技大学广州&#xff5c;先进材料学域博士招生宣讲会—南开大学专场 时间&#xff1a;2025年4月25日&#xff08;星期五&#xff09;10:00 地点&#xff1a;南开大学八里台校区中心实验室报告厅 宣讲嘉宾&#xff1a; 李昊翔 助理教授 TAN Chee Keong 助理教授 教授亲…...

异构迁移学习(无创脑机接口中的跨脑电帽迁移学习)

本文介绍BCI中的跨脑电帽的迁移学习最新算法。 (发表于2025 arxiv,应该属于投稿阶段,这个场景具有非常不错的研究意义和前景) 最新跨脑电帽异构算法github开源代码 SDDA算法原文 一、脑机接口绪论 脑机接口(BCI)指在人或动物大脑与外部设备之间创建的直接连接,通过脑…...

若依项目部署小结

参考视频&#xff1a;前后端分离式项目实战部署 | CodeSheep 环境搭建 虚拟机环境&#xff1a;jdk1.8 tomcat9 nginx A &#xff1a;虚拟机A运行前端项目 A B&#xff1a;虚拟机B运行war包 B C&#xff1a;虚拟机C运行jar包 C mysql和redis连的是C主机 前端项目部署 必备&…...

多智能体系统的中间件架构

多智能体系统&#xff08;Multi-Agent Systems, MAS&#xff09;是一种由多个智能体&#xff08;Agents&#xff09;组成的分布式系统&#xff0c;这些智能体能够自主地感知环境、做出决策并与其他智能体进行交互。 中间件&#xff08;Middleware&#xff09;在多智能体系统中…...

Eliciting Causal Abilities in Large Language Models for Reasoning Tasks

Eliciting Causal Abilities in Large Language Models for Reasoning Tasks | Proceedings of the AAAI Conference on Artificial Intelligencehttps://ojs.aaai.org/index.php/AAAI/article/view/33669 1. 概述 大型语言模型(Large Language Models, LLMs)面临的一...

DeepSeek+Mermaid:轻松实现可视化图表自动化生成(附实战演练)

目录 一、引言&#xff1a;AI 与图表的梦幻联动二、DeepSeek&#xff1a;大语言模型新星崛起2.1 DeepSeek 全面剖析2.2 多场景应用示例2.2.1 文本生成2.2.2 代码编写 三、Mermaid&#xff1a;代码式图表绘制专家3.1 Mermaid 基础探秘3.2 语法与图表类型详解3.2.1 流程图&#x…...

LeetCode第164题_最大间距

LeetCode 第164题&#xff1a;最大间距 题目描述 给定一个无序的数组 nums&#xff0c;返回 数组在排序之后&#xff0c;相邻元素之间最大的差值 。如果数组元素个数小于 2&#xff0c;则返回 0 。 您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。 难度…...

什么是DDD?为什么它正在取代传统架构?

什么是DDD&#xff1f;为什么它正在取代传统架构&#xff1f; 1. 传统开发模式的痛点 在经典的MVC架构中&#xff0c;开发流程往往从数据库表结构设计开始&#xff0c;业务逻辑散落在Service层&#xff0c;随着需求迭代容易形成「大泥球」代码&#xff1a; 实体类变成纯粹的…...

Vue3父子组件数据双向同步实现方法

在 Vue 3 中&#xff0c;实现父子组件间双向同步响应式对象的步骤如下&#xff1a; 实现思路 父组件通过 v-model 传递响应式对象。 子组件接收并深拷贝为本地副本。 子组件监听父组件的数据变化&#xff0c;更新本地副本&#xff08;不触发同步&#xff09;。 子组件监听本…...

一些基本的 Vue 规范

一、项目结构规范 推荐的目录结构 src/ ├── assets/ # 静态资源&#xff08;如图片、字体&#xff09; ├── components/ # 全局组件 ├── views/ # 页面组件&#xff08;用于路由&#xff09; ├── router/ # 路由配置 ├── store/…...

面试篇:Java并发与多线程

基础概念 什么是线程&#xff1f;线程和进程的区别是什么&#xff1f; 线程 是程序执行的最小单位&#xff0c;它是 CPU 调度和执行的基本单元。一个进程可以包含多个线程&#xff0c;这些线程共享进程的资源&#xff08;如内存&#xff09;&#xff0c;但每个线程有自己的栈…...