[STM32 - 野火] - - - 固件库学习笔记 - - - 十六.在SRAM中调试代码
一、简介
在RAM中调试代码是一种常见的嵌入式开发技术,尤其适用于STM32等微控制器。它的核心思想是将程序代码和数据加载到微控制器的内部RAM(SRAM)中运行,而不是运行在Flash存储器中。这种方法在开发过程中具有显著的优势,但也有一些限制。
1.1 为什么要在RAM中调试代码?
-
1、保护Flash存储器:
-
Flash存储器的寿命有限:Flash存储器的擦写次数是有限的(例如,STM32的Flash通常支持10,000次擦写)。频繁的调试和代码烧录可能会加速Flash的磨损。
-
减少擦写次数:将代码运行在RAM中可以避免对Flash的频繁擦写,从而延长Flash的使用寿命。
-
-
2、提高调试效率:
-
快速修改和测试:在RAM中运行代码时,可以快速修改代码并重新加载,而无需擦除和重新烧录Flash。这大大加快了调试速度。
-
动态调试:RAM中的代码可以动态修改,适合进行复杂的调试和测试,例如实时修改变量或函数逻辑。
-
-
3、支持高级调试功能:
-
断点和单步调试:在RAM中运行代码时,调试器可以更灵活地设置断点和进行单步调试,而不会受到Flash存储器的限制。
-
动态内存分配:某些调试功能(如动态内存分配和堆栈跟踪)在RAM中更容易实现。
-
1.2 在RAM中调试代码的优势
-
1、在RAM上调试程序时,下载速度非常快:
与内部FLASH相比,RAM存储器的写入速度要快得多,且无需擦除过程。因此,程序几乎是秒下,这为需要频繁修改代码的调试过程节省了大量时间,省去了烦人的擦除与写入FLASH的步骤。此外,虽然STM32的内部FLASH可擦除次数通常为1万次,一般的调试过程不太可能达到这个次数导致FLASH失效,但这也确实是一个考虑使用RAM的因素。
-
2、在RAM上调试程序时,不会改写内部FLASH的原有程序。
-
3、对于内部FLASH被锁定的芯片,还可以将解锁程序下载到RAM上,进行解锁操作。
1.3 在RAM中调试代码的缺陷
-
1、存储在RAM中的程序在掉电后会丢失,无法像存储在FLASH中那样持久保存。
-
2、如果使用STM32的内部SRAM存储程序,程序的执行速度与在FLASH上执行时基本相同,但内部SRAM的空间相对较小,可能会限制程序的大小。
-
3、如果使用外部扩展的SRAM存储程序,虽然程序空间可以非常大,但STM32读取外部SRAM的速度比读取内部FLASH慢,这会导致程序的总执行时间增加。因此,在外部SRAM中调试的程序无法完全模拟在内部FLASH中运行时的真实环境。
- 此外,STM32无法直接从外部SRAM启动,且将应用程序复制到外部SRAM的过程较为复杂(在下载程序之前,需要确保STM32能够正常控制外部SRAM)。因此,实际开发中很少会在STM32的外部SRAM中调试程序。
二、STM32的启动方式
CM-3 内核在离开复位状态后的工作过程如下图:
-
1、从地址 0x00000000 处取出栈指针 MSP 的初始值,该值就是栈顶的地址。
- 程序局部变量存储在栈空间中,MSP指向栈顶,防止栈溢出。
-
2、从地址 0x00000004 处取出程序指针 PC 的初始值,该值指向复位后应执行的第一条指令。
上述过程由内核自动设置运行环境并执行主体程序,因此它被称为自举过程。
2.1 MSP指针
MSP(Main Stack Pointer,主堆栈指针)是用于管理堆栈的一个重要寄存器,系统复位后,MSP的值会被设置为向量表的第一个值(通常是堆栈的初始地址),用于初始化堆栈。
Stack_Size EQU 0x00000400 // 定义了堆栈的大小为 0x00000400 字节(1024 字节)
AREA STACK, NOINIT, READWRITE, ALIGN=3 // 定义了一个名为 STACK 的内存区域,该区域未初始化(NOINIT),可读写(READWRITE),并且对齐到 2^3(即 8 字节)边界。
Stack_Mem SPACE Stack_Size // 在堆栈区域中分配了 Stack_Size 大小的空间。
__initial_sp // 表示堆栈指针的初始值将被设置为 Stack_Mem 的地址加上 Stack_Size 的大小,即堆栈空间的顶部。
2.2 PC指针
PC指针(程序计数器)是一个寄存器,用于存储下一条指令的地址。
-
1、系统复位后,首先调用 SystemInit 函数来初始化硬件;
-
2、然后跳转到 __main 函数,由它完成C运行时环境的初始化(如全局变量的初始化);
-
3、最终,程序会跳转到 main() 函数(由 __main 调用),开始执行用户程序。
PC指向Reset_Handler,跳转到Reset_Handler函数执行初始化时钟、调用main函数,最终进入main函数中执行程序。
2.3 STM32的三种启动方式
虽然内核默认访问的地址是 0x00000000 和 0x00000004,但这些地址实际上可以被重映射到其他地址空间。以 STM32F103 为例,根据芯片引脚 BOOT0 和 BOOT1 的电平状态,这两个地址可以被映射到内部 FLASH、内部 SRAM 或系统存储器。具体的映射配置取决于 BOOT 引脚的不同设置,具体映射关系见表 BOOT 引脚设置对 0 地址的映射。
当内核离开复位状态后,会从映射的地址中获取初始值,分别赋给主堆栈指针(MSP)和程序计数器(PC),然后开始执行指令。通常,我们会根据这些地址所映射到的存储器类型(如内部FLASH、SRAM或系统存储器)来区分不同的自举过程。
2.3.1 内部 FLASH 启动方式
当芯片上电后,若采样到 BOOT0 引脚为低电平,则 0x00000000 和 0x00000004 地址会被映射到内部 FLASH 的首地址 0x08000000 和 0x08000004。因此,内核在离开复位状态后,会从内部 FLASH 的 0x08000000 地址读取内容并赋值给主堆栈指针(MSP),作为栈顶地址;再从内部 FLASH 的 0x08000004 地址读取内容并赋值给程序计数器(PC),作为第一条指令的地址。具备这两个条件后,内核便开始从 PC 指向的地址中读取并执行指令。
2.3.2 内部 SRAM 启动方式
当芯片上电后,若采样到 BOOT0 和 BOOT1 引脚均为高电平,则 0x00000000 和 0x00000004 地址会被映射到内部 SRAM 的首地址 0x20000000 和 0x20000004。此时,内核会从 SRAM 空间获取内容以完成自举过程。
在实际应用中,0x00000000 和 0x00000004 地址存储的内容由启动文件(如 startup_stm32f10x.s)定义。而在链接阶段,分散加载文件(.sct 文件)会决定这些内容的最终存储位置,即它们会被分配到内部 FLASH 还是内部 SRAM。
2.3.3 内部 SRAM 启动方式
当芯片上电后,若采样到 BOOT0 引脚为高电平且 BOOT1 引脚为低电平时,内核将从系统存储器的 0x1FFFF000 和 0x1FFFF004 地址获取主堆栈指针(MSP)和程序计数器(PC)的值进行自举。
系统存储器是一段特殊的存储空间,用户无法直接访问。ST公司在芯片出厂前在系统存储器中固化了一段代码。当使用系统存储器启动时,内核会执行这段代码,该代码运行时会为 ISP(In System Program,系统内编程) 提供支持。具体来说,它会检测通过 USART1/2、CAN2 或 USB 通讯接口传输过来的信息,并根据这些信息更新内部 FLASH 的内容,从而实现产品应用程序的升级。因此,这种启动方式也被称为 ISP 启动方式。
三、内部FLASH的启动过程
在启动代码的中间部分,通过汇编指令 DCD(Define Constant Data),将 __initial_sp 和 Reset_Handler 的地址定义在了代码段的最前面,从而确保它们被放置在指定的地址空间。
在启动文件中,将栈顶地址和首条指令地址(__initial_sp 和 Reset_Handler)放置在代码的最前面,但这并不直接指定它们的绝对地址。这些内容的绝对地址是由链接器根据分散加载文件**(*.sct)**分配的。
上图为 STM32F103 的默认分散加载文件配置。
-
LR_IROM1:表示一个加载区域(Load Region),名称为 LR_IROM1。
- 0x08000000:加载区域的起始地址(这里是内部FLASH的起始地址);0x00080000:加载区域的大小(这里是512KB)。
-
ER_IROM1(内部FLASH):表示一个执行区域(Execution Region),名称为 ER_IROM1。
- 0x08000000:执行区域的起始地址(与加载地址相同,表示代码加载后直接在该地址执行);0x00080000:执行区域的大小(这里是 512KB)。
-
代码段分配:
*.o (RESET, +First) // 将所有对象文件中定义的 RESET 段(通常是中断向量表和复位处理程序)放在最前面。 *(InRoot$$Sections) // 将所有对象文件中定义的 InRoot 段(通常是启动代码和初始化代码)放在后面。 .ANY (+RO) // 将所有只读(Read-Only)段分配到该区域。 .ANY (+XO) // 将所有可执行但不读取的段分配到该区域。
如果把*.o (RESET, +First)放到RW_IRAM1中,那么MSP指针跟PC指针就会指向0x20000000跟0x20000004的地址。
-
RW_IRAM1(RAM空间):表示一个读写区域(Read-Write Region),名称为 RW_IRAM1。
-
0x20000000:读写区域的起始地址(这里是内部 SRAM 的起始地址);0x00010000:读写区域的大小(这里是 64KB)。
-
.ANY (+RW +ZI):将所有读写(Read-Write)和零初始化(Zero-Initialized)的段分配到该区域。
-
在分散加载文件中,加载区和执行区的首地址都被设置为 0x08000000,这恰好是内部 FLASH 的起始地址。因此,汇编文件中定义的栈顶地址和首条指令地址会被存储到 0x08000000 和 0x08000004 的地址空间中。
类似地,如果修改分散加载文件,将加载区和执行区的首地址设置为内部 SRAM 的起始地址 0x20000000,那么栈顶地址和首条指令地址将会被存储到 0x20000000 和 0x20000004 的地址空间中。
四、将代码修改为RAM自举
- 1、设置一个RAM调试的工程:
- 2、在C/C++中添加宏VECT_TAB_SRAM:
此宏在SystemInit函数中。
如果定义了 VECT_TAB_SRAM,则将中断向量表重定向到内部 SRAM 的指定位置;
如果未定义 VECT_TAB_SRAM,则将中断向量表重定向到内部 FLASH 的指定位置。
注意,两个宏之间用","分开。
-
3、打开.sct文件:
-
4、修改.sct文件,把程序分配到SRAM:
修改前的空间大小。
修改后的空间大小:原本的RAM空间为64K,现分一半用来做FLASH,一半用来做RAM
-
5、修改下载配置,把程序下载到SRAM:
-
选择Do not Erase是因为程序下载到RAM中,不需要修改FLASH,勾选Erase Full Chip或Erase Sectors的话会修改FLASH,导致程序下载失败。
-
RAM for Algorithm:烧录算法(Flash Programming Algorithm)预留的RAM空间。
烧录过程中的临时存储:在将程序烧录到Flash时,烧录算法需要运行,而这个算法需要一定的RAM空间来存储其运行时的数据和代码。
仅在烧录时使用:一旦烧录完成,这段RAM空间会被释放,可供应用程序(APP代码)使用。
-
-
6、修改调试器配置,初始化SP和PC指针:
/******************************************************************************/
/* Debug_RAM.ini: Initialization File for Debugging from Internal RAM */
/******************************************************************************/
/* This file is part of the uVision/ARM development tools. */
/* Copyright (c) 2005-2014 Keil Software. All rights reserved. */
/* This software may only be used under the terms of a valid, current, */
/* end user licence from KEIL for a compatible version of KEIL software */
/* development tools. Nothing else gives you the right to use this software. */
/******************************************************************************/FUNC void Setup (void) {SP = _RDWORD(0x20000000); // 设置栈指针SP,把0x20000000地址中的内容赋值到SP。PC = _RDWORD(0x20000004); // 设置程序指针PC,把0x20000000地址中的内容赋值到PC。_WDWORD(0xE000ED08, 0x20000000); // Setup Vector Table Offset Register
}LOAD %L INCREMENTAL // 下载axf文件到RAM
Setup(); //调用上面定义的setup函数设置运行环境 //g, main //跳转到main函数,本示例调试时不需要从main函数执行,注释掉了,程序从启动代码开始执行
这里是强制将SP、PC指针强制指向了0x20000000与0x20000000。
- 7、将工程更改为RAM调试的工程:
调试的时候不能点DOWNLOAD,要点DEBUG。
在DEBUG的时候,想要复位,不能点RST按键,要退出DEBUG后再重新点DEBUG。
相关文章:
[STM32 - 野火] - - - 固件库学习笔记 - - - 十六.在SRAM中调试代码
一、简介 在RAM中调试代码是一种常见的嵌入式开发技术,尤其适用于STM32等微控制器。它的核心思想是将程序代码和数据加载到微控制器的内部RAM(SRAM)中运行,而不是运行在Flash存储器中。这种方法在开发过程中具有显著的优势&#…...
nginx 反向代理 配置请求路由
nginx | 反向代理 | 配置请求路由 nginx简介 Nginx(发音为“Engine-X”)是一款高性能、开源的 Web 服务器和反向代理服务器,同时也支持邮件代理和负载均衡等功能。它由俄罗斯程序员伊戈尔西索夫(Igor Sysoev)于 2004…...
第二届粤港澳大湾区数字经济与人工智能国际学术会议(DEAI 2025)
重要信息 2025年3月28-30日 I 广东省东莞市(广东科技学院-松山湖校区) I www.icdeai.com 简介 第二届粤港澳大湾区数字经济与人工智能(DEAI 2025)将在2025年3月28-30日在广东省东莞市隆重举行。来自国内外高等院校、科学研究所、企事业单位的专家、教授、学者、…...
使用GDI+、文件和目录和打印API,批量将图片按文件名分组打包成PDF
代码写了两个小时,速度太慢(包括学习文档的时间) #include <stdio.h> #include <Windows.h> #include <gdiplus.h> #include <string.h> using namespace Gdiplus; #pragma comment(lib, "Gdiplus.lib") …...
贪心算法
int a[1000], b5, c8; swap(b, c); // 交换操作 memset(a, 0, sizeof(a)); // 初始化为0或-1 引导问题 为一个小老鼠准备了M磅的猫粮,准备去和看守仓库的猫做交易,因为仓库里有小老鼠喜欢吃的五香豆,第i个房间有J[i] 磅的五香豆…...
如何查询网站是否被百度蜘蛛收录?
一、使用site命令查询 这是最直接的方法。在百度搜索框中输入“site:你的网站域名”,例如“site:example.com”(请将“example.com”替换为你实际的网站域名)。如果搜索结果显示了你的网站页面,并且显示了收录的页面数量…...
Hutool - Log:自动识别日志实现的日志门面
一、简介 在 Java 开发中,日志记录是一项非常重要的功能,它可以帮助开发者在开发和生产环境中监控程序的运行状态、排查问题。然而,Java 生态系统中有多种日志实现框架,如 Log4j、Logback、JDK 自带的日志框架等。为了在不同的项…...
【GPU驱动】- 状态机
一、概述 Mesa 是一个开源的图形库,它提供了一个通用的图形抽象层,支持多种硬件和驱动程序。Mesa 的核心组件之一是 State Tracker,它在抽象图形 API(如 OpenGL )与具体的图形驱动之间起到桥梁作用。State Tracker 通…...
rtcwake - Linux下定时唤醒计算机
rtcwake 是一个用于通过实时时钟(RTC)唤醒计算机的工具。它常用于在 Linux 系统中设置计算机在指定时间自动唤醒或关闭。以下是对命令 rtcwake -m off -s ${sleep_time} 的详细解析: 命令解析 bash复制 rtcwake -m off -s ${sleep_time} 1…...
MySQL 日志
MySQL 日志 慢查询日志(Slow query log) 慢查询⽇志由执⾏时间超过系统变量 long_query_time 指定的秒数的SQL语句组成,并且检 查的⾏数⼤于系统变量 min_examined_row_limit 指定值。被记录的慢查询需要进⾏优化, 可以使⽤mysqldumpslow客⼾端程序对慢…...
C++ 泛型编程之补充(class 和typename)
目录 1.class 和 typename 可互换 1.1 template 和 template 在模板参数列表中完全一样,可以互换使用。 2.什么时候 class 和 typename 不一样? 2.1 嵌套依赖类型 时必须用typename 重点说明: 2.2 普通作用域(不能互换&…...
[MDM 2024]Spatial-Temporal Large Language Model for Traffic Prediction
论文网址:[2401.10134] Spatial-Temporal Large Language Model for Traffic Prediction 论文代码:GitHub - ChenxiLiu-HNU/ST-LLM: Official implementation of the paper "Spatial-Temporal Large Language Model for Traffic Prediction" …...
跟着 Lua 5.1 官方参考文档学习 Lua (6)
文章目录 2.11 – Coroutines 2.11 – Coroutines Lua supports coroutines, also called collaborative multithreading. A coroutine in Lua represents an independent thread of execution. Unlike threads in multithread systems, however, a coroutine only suspends i…...
Spring Cloud — Hystrix 服务隔离、请求缓存及合并
Hystrix 的核心是提供服务容错保护,防止任何单一依赖耗尽整个容器的全部用户线程。使用舱壁隔离模式,对资源或失败单元进行隔离,避免一个服务的失效导致整个系统垮掉(雪崩效应)。 1 Hystrix监控 Hystrix 提供了对服务…...
加油站(力扣134)
既然每一个加油站都有对应的加油量和耗油量,我们不妨计算一下每个加油站的汽油净增量。如果每个加油站净增量之和不为负数,则说明一定可以找到唯一的起始点。那我们该如何找到这个起始点呢?我们设置最开始的起点为第0个加油站,接着…...
科普:你的笔记本电脑中有三个IP:127.0.0.1、无线网 IP 和局域网 IP;两个域名:localhost和host.docker.internal
三个IP 你的笔记本电脑中有三个IP:127.0.0.1、无线网 IP 和局域网 IP。 在不同的场景下,需要选用不同的 IP 地址,如下为各自的特点及适用场景: 127.0.0.1(回环地址) 特点 127.0.0.1 是一个特殊的 IP 地…...
Golang 相关的github 开源项目
1. pan-light url: http://github.com/peterq/pan-lightstar: 12.1kfork: 2.5kwatch: 284 用Golang和Qt5编写的不限速版百度网盘。相比之前版本的百度网盘客户端,当前版本拥有更友好、便捷的图形界面,体量更轻,便于使用,只需下载…...
数据结构《图》
数据结构《图论》 图的性质 一、无向图(Undirected Graph) 定义 由一组顶点(Vertex)和一组无向边(Edge)构成。 每条无向边用一条无方向的线段连接两个顶点,记为 ( (u, v) ),其中…...
WPF实现打印机控制及打印
在WPF中实现打印机控制和打印功能,通常需要使用System.Printing命名空间中的类来管理打印机和打印任务。以下是一个简单的示例,展示如何在WPF应用程序中实现打印功能。 1. 添加必要的引用 首先,确保在项目中引用了System.Printing命名空间。…...
springboot系列十四: 注入Servlet, Filter, Listener + 内置Tomcat配置和切换 + 数据库操作
文章目录 注入Servlet, Filter, Listener官方文档基本介绍使用注解方式注入使用RegistrationBean方法注入DispatcherServlet详解 内置Tomcat配置和切换基本介绍内置Tomcat配置通过application.yml完成配置通过类配置 切换Undertow 数据库操作 JdbcHikariDataSource需求分析应用…...
DeepSeek 助力 Vue 开发:打造丝滑的二维码生成(QR Code)
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…...
从传统到轻量级5G:网络架构演变与优化路径
轻量级5G 随着5G技术的不断发展,通信网络架构正经历着前所未有的变革。传统的5G核心网架构虽然在性能和容量方面表现出色,但在灵活性、部署效率以及成本控制方面却面临一些挑战。为了应对日益复杂的通信需求,轻量级5G核心网成为了一种…...
独立开发者如何寻找产品设计灵感
作为独立开发者,面对激烈的市场竞争和不断变化的用户需求,寻找优秀的产品设计灵感是至关重要的一步。以下是一篇关于独立开发者如何寻找产品设计灵感的教程,希望能为你提供一些有益的指导。 一、观察日常生活 1.1 关注身边的小问题 在日常生…...
技术解析 | 适用于TeamCity的Unreal Engine支持插件,提升游戏构建效率
龙智是JetBrains授权合作伙伴、Perforce授权合作伙伴,为您提供TeamCity、Perforce Helix Core等热门的游戏开发工具及一站式服务 TeamCity 是游戏开发的热门选择,大家选择它的原因包括支持 Perforce、可以进行本地安装,并提供了多种配置选项。…...
uniapp h5端和app端 使用 turn.js
前提:添加页后,添加页与当前页会重叠在一起,不知道为什么,没有找到解决办法 1.h5端 <template><view class"container"><view id"flipbook"><view class"page page1">Page 1</view><view class"page pag…...
智慧校园系统在学生学习与生活中的应用
随着科技的快速发展,智慧校园系统逐渐成为现代教育不可或缺的一部分。它整合了先进的信息技术、物联网技术以及人工智能等,旨在构建一个全面、智能、个性化的学习与生活环境。对于学生而言,这一系统不仅能够极大地提高学习效率,还…...
umi: valtio的使用
一、基本用法 import { proxy, useSnapshot } from umijs/max;// 1、定义数据 const state proxy({ count: 33 });export default () > {// 2、使用数据const snap useSnapshot(state);function increaseCount() {state.count 1;}return (<><h1>{snap.count}…...
什么是矩阵账号?如何高效运营tiktok矩阵账号
…...
C语言.h头文件的写法
头文件的内容 #ifndef __SEQUENCE_LIST_H // 定义以防止递归包含 #define __SEQUENCE_LIST_H // (1)、其它头文件 #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <stdbool.h> // (2)、宏定义(函数、变量、常量) // (3)、…...
【Day44 LeetCode】图论问题 Ⅱ
一、图论问题 Ⅱ 1、岛屿的最大面积 这题和上一篇博客求岛屿数量如出一辙,都是要找出所有岛屿,深度优先搜索代码如下: # include<iostream> # include<vector>using namespace std;int dfs(vector<vector<int>> …...
设计模式教程:责任链模式(Chain of Responsibility Pattern)
责任链模式(Chain of Responsibility Pattern)是一种常用的设计模式,它属于行为型模式,主要解决的是多个对象处理一个请求时,如何解耦请求的发送者和接收者,以及如何将请求的处理职责分配给不同的对象。 1…...
java网络编程
计算机网络基础 网络编程的目的就是直接或间接地通过网络协议与其他计算机进行通信。 在 Java 语言中包含网络编程所需要的各种类,编程人员只需要创建这些类的对象,调用相应的方法,就可以进行网络应用程序的编写。 要进行网络程序的编写&am…...
计算机网络面试知识点总结
目录 1. 计算机网络的基本知识点2. OSI 七层模型3. TCP/IP 四层模型4. TCP 和 UDP4.1 TCP 协议4.2 TCP 流量控制4.3 TCP 拥塞控制4.4 TCP 三次握手4.5 TCP 四次挥手4.6 TCP 粘包问题4.7 TCP Socket交互流程4.8 UDP 协议以及和 TCP 协议的不同 5. HTTP协议5.1 HTTP 请求方法以及…...
ubuntu22.4搭建单节点es8.1
下载对应的包 elasticsearch-8.1.1-linux-x86_64.tar.gz 创建es租户 groupadd elasticsearc useradd elasticsearch -g elasticsearch -p elasticsearch chmod uw /etc/sudoers chmod -R elasticsearch:elasticsearch elasticsearch 修改配置文件 vim /etc/sysctl.conf vm…...
卷积与动态特征选择:重塑YOLOv8的多尺度目标检测能力
文章目录 1. YOLOv8的网络结构概述2. 添加注意力机制2.1 为什么添加注意力机制?2.2 如何将注意力机制集成到YOLOv8中?2.3 效果分析 3. C2f模块的集成3.1 C2f模块简介3.2 如何在YOLOv8中集成C2f模块?3.3 效果分析 4. 卷积操作的优化4.1 卷积操…...
【Altium Designer】差分对等长设置以及绕线
在Altium Designer 17中设置差分对的等差规则及绕等长操作,需结合规则配置与交互式布线工具完成。以下是详细操作步骤: 目录 一、差分对等差规则设置 1. 原理图端差分对定义 2. PCB端差分规则配置 二、差分对等长绕线操作 1. 差分对布线 2. 交互式…...
BFS 和 DFS(深度优先搜索、广度优先搜索)
深度优先搜索(DFS)和广度优先搜索(BFS)是两种常用的图遍历算法,用于解决图相关的问题。它们在搜索问题中具有广泛的应用,如路径搜索、连通性检测等。 以下是具体区别: (图片引自&am…...
汽车免拆诊断案例 | 2013 款奔驰 S300L 车起步时车身明显抖动
故障现象 一辆2013款奔驰S300L车,搭载272 946发动机,累计行驶里程约为15万km。车主反映,将挡位置于D挡,稍微释放一点制动踏板,车辆蠕动时车身明显抖动,类似气缸失火时的抖动,又类似手动变速器…...
基于UnrealEngine(UE5)的太空探索
视频部分可参见:https://www.bilibili.com/video/BV1JWA8eSEVg/ 中国 天宫号 空间站 人造卫星可视化 星链卫星可视化 小行星分布及运动轨迹可视化 月球基地 可视化 八大行星轨道 太阳系宜居带可视化 阿波罗8号拍摄的地球升起 谷神星模型及轨迹可视化 星座可视化 十…...
HTML Application(hta)入门教程
简介 HTA是HTML Application的缩写,又称为HTML应用程序。 hta是一个可执行文件,双击可以直接运行 hta与html非常相似,可直接将文件后缀改为.hta来获得HTA格式的文件。 支持VBS和JavaScript html的权限被限制在网页浏览器内,只有操…...
IOS UITextField 无法隐藏键盘问题
设置UITextField 键盘按钮返回键为“完成”,即return key 设置done .m代码设置代理 //设置代理协议 UITextFieldDelegate, self.mobileTextField.delegate self; ///点击完成键隐藏键盘 - (BOOL)textFieldShouldReturn:(UITextField *)textField{//取…...
ES6箭头函数:基础与进阶指南
目录 引言 一、基础篇:核心语法与特性 1.1 语法革新 1.2 this绑定机制 二、进阶篇:深度特性解析 2.1 闭包中的this继承 2.2 限制与注意事项 三、实践指南:应用场景与陷阱规避 3.1 推荐使用场景 3.2 应避免的场景 四、性能考量 结语…...
AI赋能编程:PyCharm与DeepSeek的智能开发革命
在这个智能化的时代,人工智能技术正在深刻地改变着我们的工作方式,尤其是在编程领域。无论是初学者还是资深开发者,都希望借助更高效的工具和智能助手来提升生产力、优化代码质量。今天,我们将聚焦于两个强大的工具:Py…...
在Spring Boot中如何使用Freemaker模板引擎
在 Spring Boot 中使用 FreeMarker 模板引擎可以帮助你创建动态的 Web 页面。以下是详细的步骤和示例代码,介绍如何在 Spring Boot 项目里集成和使用 FreeMarker。 1. 添加依赖 如果你使用的是 Maven 项目,需要在 pom.xml 文件中添加 FreeMarker 相关依赖。Spring Boot 提供…...
【论文精读】VLM-AD:通过视觉-语言模型监督实现端到端自动驾驶
论文地址: VLM-AD: End-to-End Autonomous Driving through Vision-Language Model Supervision 摘要 人类驾驶员依赖常识推理来应对复杂多变的真实世界驾驶场景。现有的端到端(E2E)自动驾驶(AD)模型通常被优化以模仿…...
【HarmonyOS Next】鸿蒙应用进程和线程详解
【HarmonyOS Next】鸿蒙应用进程和线程详解 一、前言 进程的定义: 进程是系统进行资源分配的基本单位,是操作系统结构的基础。 在鸿蒙系统中,一个应用下会有三类进程: (1) 主进程, (2) ExtensionAbility进程ÿ…...
基于深度学习的信号滤波:创新技术与应用挑战
一、引言 1.1 研究背景 随着科技的不断发展,信号处理领域面临着越来越复杂的挑战。在众多信号处理技术中,基于深度学习的信号滤波技术逐渐崭露头角,成为研究的热点。 基于深度学习的信号滤波在信号处理领域具有至关重要的地位。如今&#…...
从【人工智能】到【计算机视觉】,【深度学习】引领的未来科技创新与变革
前几天偶然发现了一个超棒的人工智能学习网站,内容通俗易懂,讲解风趣幽默,简直让人欲罢不能。忍不住分享给大家,点击这里立刻跳转,开启你的AI学习之旅吧! 前言 – 人工智能教程https://www.captainbed.cn/l…...
什么是方法
System.out.println(),那么它是什么呢? Java方法是语句的集合,它们在一起执行一个功能。 方法是解决一类问题的步骤的有序组合 方法包含于类或对象中 方法在程序中被创建,在其他地方被使用 这段Java代码出现错误的原因在于,在…...
Python strip() 方法详解:用途、应用场景及示例解析(中英双语)
Python strip() 方法详解:用途、应用场景及示例解析 在 Python 处理字符串时,经常会遇到字符串前后存在多余的空格或特殊字符的问题。strip() 方法就是 Python 提供的一个强大工具,专门用于去除字符串两端的指定字符。本文将详细介绍 strip(…...