MCU烧录地址原理与实战:从启动逻辑到芯片手册定位
2026/9/14 2:48:39 网站建设 项目流程

1. 烧录地址不是“随便填的数字”,而是芯片启动逻辑的密码本

你手里的那块STM32开发板,插上USB线、点下Keil或PlatformIO的“Download”按钮,程序就跑起来了——但你有没有盯着那个弹窗里一闪而过的“Programming at address 0x08000000…”愣过神?为什么不是0x00000000?为什么不是0x1000?为什么有些ESP32项目烧录时显示0x6000,而STC51单片机却死死咬住0x0000?这不是IDE的随机发挥,更不是烧录工具在“碰运气”,而是每一块单片机芯片出厂时就刻进硅片底层的地址映射规则在说话。它决定了:CPU上电那一瞬间,从哪条物理地址线开始取第一条指令;Bootloader从哪里加载用户代码;Flash和RAM在地址空间里如何排兵布阵;甚至决定了你改错一个地址,整块板子就变砖头还是照常工作。我干嵌入式这十多年,亲手调试过不下两百种MCU型号,从8位STC89C52到32位NXP i.MX RT1064,踩过最深的坑,90%都跟这个“烧录地址”有关——不是代码写错了,是地址填错了;不是硬件坏了,是映射关系没吃透。这篇文章不讲抽象理论,只说你每天在Keil、STM32CubeProgrammer、esptool.py里真实面对的场景:为什么0x08000000在STM32F103上是黄金标准,到了STM32H7就变成0x08020000;为什么ESP32-C3的固件必须从0x6000起始,而ESP32-S3却要分三段烧录;为什么用STC-ISP烧51单片机永远只能选0x0000,换到CH32V203就得看DIP开关位置。我会带你一层层剥开“地址”这个看似简单的数字背后的三重真相:芯片物理存储器的布局(Hardware Layout)、复位向量表的硬编码位置(Vector Table)、以及Bootloader对用户代码的加载约定(Boot Protocol)。你看完就能自己查芯片手册,三分钟内判断出新拿到的GD32E230该烧到哪个地址,再也不用靠百度搜“stm32f407烧录地址是多少”这种问题碰运气。

1.1 烧录地址的本质:不是“写入位置”,而是“CPU启动时看的第一眼”

很多人把“烧录地址”理解成“我把程序文件塞进Flash的第几个字节”,这是个危险的误解。真正关键的,是CPU复位后执行的第一条指令,必须从这个地址开始读取。我们以最经典的STM32F103C8T6(俗称“蓝 pill”)为例:它的主Flash起始物理地址确实是0x08000000,容量64KB,所以地址范围是0x08000000 ~ 0x0800FFFF。但如果你把程序烧到0x08001000,上电后CPU依然会从0x08000000取指令——结果就是读到一堆未编程的0xFF,直接跳进非法指令陷阱,芯片卡死。这就是为什么Keil默认生成的分散加载文件(scatter file)里,ER_IROM1段永远定义为0x08000000:它强制要求你的代码镜像,必须把复位向量(Reset Handler)放在这个地址的前四个字节。向量表不是可选配置,是ARM Cortex-M内核的硬性规定:地址0x00000000处存放初始栈顶指针(MSP),0x00000004处存放复位中断服务程序入口地址。那么问题来了:为什么不是直接从0x00000000启动?因为STM32的系统存储器(System Memory)在0x1FFFF000,而主Flash在0x08000000,芯片通过BOOT引脚状态决定启动源。当BOOT0=0且BOOT1=x时,芯片将0x08000000处的Flash内容映射到0x00000000地址空间。也就是说,物理地址0x08000000被“镜像”到了0x00000000这个CPU永远信任的起始地址。你烧录时填0x08000000,是因为这是Flash的物理起始地址;CPU执行时访问0x00000000,是因为硬件做了地址映射。这个“物理地址”和“映射地址”的分离,正是所有地址混乱的根源。我第一次调试GD32F303时就栽在这儿:手册写Flash从0x08000000开始,我照填,结果程序不跑。后来发现GD32的向量表偏移寄存器(VTOR)默认指向0x08000000,但它的系统启动流程要求用户代码必须把向量表放在0x08000000,而Keil工程里忘了勾选“Use Memory Layout from Target Dialog”,导致链接器把向量表放到了0x08000100,CPU一上电就读错地址,当场罢工。所以记住:烧录地址是你告诉烧录工具“把二进制数据写到Flash芯片的哪个物理位置”,而启动地址是CPU复位后“从地址空间的哪个逻辑位置开始取指令”。两者一致,才能跑起来。

1.2 为什么0x00000000有时能用,有时绝对不行?

看到这里,你可能会想:“既然CPU最终访问的是0x00000000,那我直接把程序烧到0x00000000不就行了?”——理论上可行,现实中几乎必死。原因有三:第一,0x00000000在绝大多数32位MCU中,根本就不是Flash的物理地址。它是ARM Cortex-M内核定义的“向量表起始地址”,是一个逻辑地址空间概念,由芯片内部总线矩阵(Bus Matrix)和存储器控制器(Memory Controller)负责将其映射到真实的物理存储器。比如STM32F407,它的SRAM1起始物理地址是0x20000000,但你可以通过设置VTOR寄存器,让CPU把0x00000000这个逻辑地址映射到SRAM1的0x20000000,从而实现向量表重定位。但0x00000000本身没有对应的物理存储器,你往这儿烧录,烧录工具会直接报错“Address out of range”。第二,即使芯片支持从0x00000000启动(如某些带内置ROM的MCU),这个地址通常被预留给厂商Bootloader或安全启动密钥区,用户代码无权写入。第三,也是最实际的一点:所有主流烧录工具(J-Link、ST-Link、esptool)的底层驱动,都是按芯片厂商提供的Flash算法(Flash Algorithm)工作的,而这些算法严格限定在芯片手册定义的Flash物理地址范围内操作。你强行指定0x00000000,工具要么拒绝执行,要么把数据写进未知区域导致芯片锁死。我见过最离谱的案例是一个学生用OpenOCD烧STM32L0,误把地址设成0x00000000,结果OpenOCD真的尝试擦除0x00000000~0x00000FFF区域,而这片区域恰好是芯片的Option Bytes(选项字节)存储区,一擦全毁,芯片再也无法识别,只能报废。所以,0x00000000是CPU的“信仰地址”,不是你的“操作地址”。你要操作的,永远是芯片手册里白纸黑字写的那个物理Flash起始地址。

2. 主流MCU家族烧录地址对照与底层逻辑拆解

不同厂商、不同架构的MCU,其烧录地址差异巨大,绝非随意设定。背后是芯片设计时对存储器类型、启动模式、安全机制的综合权衡。下面我按技术路线分类,结合真实项目经验,逐个拆解那些高频出现的地址数字背后的硬核逻辑。

2.1 STM32家族:0x08000000为何成为“行业默认值”?

STM32F1/F2/F4/F7系列,0x08000000这个地址几乎成了行业共识。但它并非一成不变。我们以F103和H743为例对比:

芯片型号主Flash物理起始地址容量启动映射地址典型烧录地址关键差异说明
STM32F103C8T60x0800000064KB0x00000000 (映射自0x08000000)0x08000000标准配置,向量表固定在此
STM32H743VI0x080000002MB0x00000000 (映射自0x08000000)0x08000000Flash大了,但起始地址不变
STM32H743VI (双Bank模式)Bank1: 0x08000000, Bank2: 0x08100000Bank1: 1MB, Bank2: 1MB可配置映射Bank1或Bank2到0x000000000x08000000 或 0x08100000需通过SYSCFG->MEMRMP寄存器切换

为什么是0x08000000?答案藏在ARM的地址空间规划里。ARM Cortex-M内核将整个4GB地址空间划分为多个区域,其中0x00000000~0x1FFFFFFF被定义为“Code”区域,用于存放可执行代码。而0x08000000正好落在这个区域内,且是256MB边界(0x08000000 = 128MB),符合芯片设计时对Flash控制器地址线宽度(通常24位或25位)的优化。更重要的是,这个地址避开了低地址段的特殊用途:0x00000000~0x0000FFFF是向量表保留区,0x20000000~0x3FFFFFFF是SRAM区,0x40000000~0x5FFFFFFF是外设寄存器区。0x08000000成了一个既满足内核规范、又避开冲突、还便于Flash控制器布线的“黄金分割点”。但注意:F103的0x08000000是主Flash,而F030的Flash起始地址却是0x08000000,但容量只有16KB,所以烧录地址仍是0x08000000,只是你不能把超过16KB的程序塞进去。我做过一个F030项目,客户给的固件bin文件有24KB,我直接烧录,结果程序跑一半就跳飞——查了半天才发现是Flash溢出,覆盖了Option Bytes。所以,烧录地址正确只是第一步,你还得确认你的代码大小不超过该地址起始的Flash容量。STM32CubeMX生成的工程里,Linker Script中的FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K这一行,就是对你代码尺寸的硬性约束。一旦超限,编译器会报错,但如果你手动修改了bin文件或用了裸烧工具,这个保护就失效了。

2.2 ESP32家族:0x6000、0x1000、0x20000……为什么地址如此“碎片化”?

ESP32的烧录地址体系,堪称MCU界最复杂的之一。它不像STM32那样简单粗暴地把整个Flash当一块大蛋糕切,而是把Flash想象成一个需要精密调度的物流中心,每个地址段都有明确的“货物类型”和“送达时间”。核心在于ESP-IDF的分区表(Partition Table)机制。

  • 0x1000: 这是bootloader的烧录地址。ESP32上电后,ROM里的固有代码(First Stage Bootloader)会先从Flash的0x1000地址读取并运行用户编写的Second Stage Bootloader。这个bootloader负责初始化基本外设、校验固件、加载应用程序。它必须放在0x1000,因为ROM代码是硬编码的。
  • 0x6000: 这是partition table(分区表)的烧录地址。分区表是一个二进制结构体,定义了Flash里各个功能区的起始地址、大小和类型(如app、data、ota_data等)。ESP-IDF默认生成的分区表bin文件,必须烧录到0x6000。为什么是0x6000?因为0x1000~0x5FFF这段空间(约20KB)被预留给了bootloader的扩展空间和一些临时缓冲区。0x6000是第一个“干净”的、可供用户定义的起始点。
  • 0x10000 (0x10000): 这是应用程序(app)的默认烧录地址。但注意,这不是绝对的。分区表里可以明确定义app的起始地址。例如,一个典型的分区表CSV文件:
    # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x6000, otadata, data, ota, 0xf000, 0x2000, app0, app, ota_0, 0x10000, 0x1C0000, app1, app, ota_1, 0x1D0000, 0x1C0000,
    这里app0的Offset是0x10000,所以你的main.bin必须烧录到0x10000。但如果你把Offset改成0x20000,那烧录地址就得跟着改。这就是为什么网上有人问“怎么看esp32的烧录地址”——答案不在芯片手册,而在你项目里的partitions.csv文件。

我调试过一个ESP32-S3项目,客户要求OTA升级,但升级后设备无法启动。抓取串口日志发现,bootloader一直在报“Invalid partition table”。最后发现是分区表烧录错了地址:客户把分区表bin文件烧到了0x8000,而不是标准的0x6000。bootloader在0x6000没找到有效分区表,就放弃了后续加载,直接卡死。这个错误极其隐蔽,因为0x8000地址本身是合法的Flash空间,烧录工具不会报错,但bootloader的逻辑会彻底失效。所以,ESP32的烧录地址,本质是一套基于分区表的动态寻址协议,你必须同时管理好三个文件:bootloader.bin(0x1000)、partition-table.bin(0x6000)、your_app.bin(由分区表定义)。漏掉任何一个,或者地址错一位,整个系统就瘫痪。

2.3 8051/STC家族:0x0000的“铁律”与“例外”

对于老派的51单片机,烧录地址几乎清一色是0x0000。原因很简单:8051内核没有复杂的地址映射机制,它的程序计数器(PC)复位后直接从0x0000开始取指。STC89C52、AT89C51的Flash物理地址就是从0x0000开始的,所以烧录地址自然就是0x0000。这是一个“物理地址=逻辑地址”的直白世界。

但“例外”恰恰出现在国产新锐身上。比如STC8H系列,它虽然兼容8051指令集,但内部Flash控制器支持扇区擦除和IAP(在应用编程)。它的手册明确指出:主Flash起始地址是0x0000,但IAP功能区(用于存放IAP升级代码)位于0x7000~0x7FFF。如果你要做远程升级,就必须把IAP代码单独编译,并烧录到0x7000。这时,你的主程序烧录地址仍是0x0000,但IAP代码的烧录地址是0x7000。另一个典型是CH32V203(RISC-V内核),它采用双Bank Flash设计。Bank0(0x00000000)用于存放主程序,Bank1(0x00020000)用于OTA备份。它的烧录地址取决于你当前要更新的是哪个Bank。我帮一个客户做CH32V203的OTA方案时,就因为没搞清Bank切换机制,把新固件烧进了Bank0,而Bootloader却固执地从Bank1启动,结果新固件永远不生效。后来查手册发现,CH32V203的启动选择是由BOOT引脚和一个特殊的“启动配置字节”共同决定的,这个字节就存放在Flash的0x0001FFFC地址。所以,对这类新51/RISC-V芯片,“烧录地址”已经从单一数值,演变成了一个需要配合硬件引脚和配置字节的多维参数系统

3. 如何精准确定任意一款MCU的烧录地址?四步法实战指南

面对一款从未接触过的MCU,比如刚拿到的NXP LPC55S69或兆易创新的GD32E503,你不可能靠猜。我总结了一套经过上百个项目验证的“四步法定位法”,确保你在5分钟内得到准确答案。

3.1 第一步:查芯片手册的“Memory Map”章节——这是唯一权威来源

不要信论坛、不要信博客、不要信“别人说的”,只信芯片手册。打开PDF,Ctrl+F搜索“Memory Map”或“Address Map”。以GD32E503为例,手册第38章《Memory Organization》表格清晰列出:

  • Flash: 0x08000000 ~ 0x0807FFFF (512KB)
  • SRAM: 0x20000000 ~ 0x2001FFFF (128KB)
  • System Memory: 0x1FFFF000 ~ 0x1FFFF7FF (2KB)

这里0x08000000就是主Flash起始地址,也就是你的默认烧录地址。但注意,手册里还会有一句小字:“The boot loader in system memory is mapped to address 0x00000000 when BOOT pins are configured for system memory boot.” 这句话告诉你,如果BOOT引脚设为从系统存储器启动,那么0x1FFFF000这片ROM会被映射到0x00000000。但这跟你烧录用户程序无关,那是厂商的事。我们的目标是用户Flash,所以锁定0x08000000。

提示:有些手册会把Flash分成多个Bank,比如“Bank A: 0x08000000, Bank B: 0x08100000”。这时你需要看你的Bootloader或芯片启动配置,决定用哪个Bank。如果不确定,就用第一个Bank的起始地址。

3.2 第二步:看官方IDE或烧录工具的默认配置——它们通常已预置正确值

Keil MDK、IAR EWARM、STM32CubeIDE、ESP-IDF的idf.py,这些工具都不是凭空生成配置的。它们的芯片支持包(Device Family Pack, DFP)里,包含了芯片厂商提供的标准Flash算法和默认链接脚本。打开Keil的“Options for Target” -> “Utilities” -> “Settings”,在“Flash Download”选项卡里,你会看到一个“Add”按钮,点击后弹出的Flash算法列表,每一个算法文件(.FLM)都对应一个特定的Flash地址范围。例如,STM32F103的算法,其默认起始地址就是0x08000000。同样,在STM32CubeProgrammer里,选择芯片型号后,软件会自动填充正确的“Start Address”和“Size”。这相当于厂商给你做了“答案提示”,你只需要确认它和手册一致即可。我曾经在一个GD32项目里,Keil默认的DFP包版本太旧,不支持GD32E503的新Flash控制器,导致烧录失败。我手动下载了最新版DFP,问题立刻解决。所以,工具的默认值是可靠的,但前提是你的工具包是最新版。

3.3 第三步:分析你的工程链接脚本(Linker Script)——这是你代码的“地址契约”

无论你用Keil、GCC还是IAR,最终生成的可执行文件(.axf, .elf, .hex)都遵循一个链接脚本(scatter file, linker script)。这个脚本才是决定你的代码最终落在哪个物理地址的“宪法”。以GCC的STM32工程为例,STM32F103C8Tx_FLASH.ld文件里有这样一行:

MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K }

这里的ORIGIN = 0x08000000,就是烧录地址。如果你把这个值改成0x08001000,那么你的整个代码段(包括向量表)都会向后偏移0x1000字节。此时,你必须同时修改烧录工具里的地址为0x08001000,否则向量表就错位了。我在一个军工项目里,为了规避Flash某个已损坏的扇区,客户要求把代码整体偏移到0x08002000。我不仅改了链接脚本,还在startup文件里手动设置了SCB->VTOR = 0x08002000,确保CPU能从新的向量表地址取指。所以,链接脚本是你和烧录工具之间的“地址契约”,二者必须完全一致。

3.4 第四步:用烧录工具读取Flash内容验证——眼见为实

当以上三步都做完,最后一步是“交叉验证”。用J-Link Commander、ST-Link Utility或esptool.py,连接芯片,执行一次“Read Memory”操作,读取你怀疑的地址区域的前16字节。例如,对STM32F103,执行:

JLinkExe -CommanderScript read_flash.jlink # read_flash.jlink内容: mem32 0x08000000 4

正常情况下,你应该看到类似0x20005000 0x08000181 ...这样的输出,其中第一个32位字(0x20005000)是初始MSP值,第二个(0x08000181)是复位向量地址(最低位为1表示Thumb状态)。如果读出来全是0x00000000或0xFFFFFFFF,说明这个地址要么没烧录,要么烧录失败,要么根本就不是Flash区域。这个步骤能帮你100%排除“地址填错但工具没报错”的侥幸心理。我处理过一个客户投诉“程序烧不进去”的案例,用J-Link读取0x08000000,发现全是0xFF,但烧录日志显示“Success”。最后发现是客户用的廉价ST-Link V2 clone,固件有bug,烧录过程实际失败了,但返回了成功信号。用正版J-Link一试,立刻报错“Flash programming failed”。

4. 实操过程详解:从零开始完成一次“地址敏感型”烧录

理论懂了,现在来一次完整的、不依赖IDE的纯命令行烧录实操。我们以STM32F103C8T6为例,使用OpenOCD + GDB,全程手动控制烧录地址,让你看清每一个环节。

4.1 准备工作:获取正确的OpenOCD配置文件与Flash算法

OpenOCD不是万能的,它需要针对具体芯片的配置文件(.cfg)和Flash编程算法(.cfg)。STM32F1系列的标准配置是interface/stlink-v2.cfgtarget/stm32f1x.cfg。但关键在于,stm32f1x.cfg里定义了Flash的起始地址和大小:

# In stm32f1x.cfg set _FLASH_SIZE 0x10000 set _FLASH_BASE 0x08000000

这个_FLASH_BASE变量,就是OpenOCD进行Flash擦除和编程时使用的物理地址。如果你用的是其他芯片,比如STM32F4,就要换成target/stm32f4x.cfg,它的_FLASH_BASE是0x08000000(F4的Flash起始地址和F1一样,但容量更大)。

4.2 编译与链接:确保你的bin文件与地址匹配

假设你用GCC编译,链接脚本stm32f103c8t6.ld如下:

MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 20K } SECTIONS { .isr_vector : { *(.isr_vector) } > FLASH .text : { *(.text) } > FLASH ... }

编译命令:

arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -O2 -o main.elf main.c startup_stm32f103c8.s arm-none-eabi-objcopy -O binary main.elf main.bin

生成的main.bin,其第一个字节就对应着0x08000000地址的向量表。你可以用xxd main.bin | head -n 5查看前几行,确认是否是预期的MSP和Reset Handler值。

4.3 OpenOCD烧录命令详解:地址参数在哪里?

启动OpenOCD服务器:

openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg

然后在另一个终端,用GDB连接:

arm-none-eabi-gdb main.elf (gdb) target extended-remote :3333 (gdb) monitor flash write_image erase main.bin 0x08000000

注意最后一行命令:flash write_image erase main.bin 0x08000000。这里的0x08000000,就是你指定的烧录地址。OpenOCD会先擦除从0x08000000开始的、足够容纳main.bin的Flash扇区,然后把main.bin的数据逐字节写入。如果你把地址写成0x08001000,那么main.bin就会被写到0x08001000开始的位置,而CPU仍会从0x08000000取指,结果就是启动失败。这就是为什么这个地址参数如此关键——它直接决定了你的二进制数据在物理Flash上的落点。

4.4 烧录后验证:不只是“Success”,要看“是否真在那儿”

烧录完成后,别急着reset。先用GDB读取Flash,验证数据:

(gdb) x/8xw 0x08000000 0x08000000: 0x20005000 0x08000181 0x08000181 0x08000181 0x08000010: 0x08000181 0x08000181 0x08000181 0x08000181

看到0x20005000(MSP)和0x08000181(Reset Handler),说明向量表已正确写入。再用monitor flash probe命令,让OpenOCD重新探测Flash状态,确认没有坏块。最后,执行monitor reset halt,让CPU复位并停在第一条指令,用info registers查看PC寄存器是否为0x08000180(Reset Handler地址减1,因为Thumb模式)。一切吻合,才代表这次烧录真正成功。

5. 常见问题与排查技巧实录:那些年我们填错地址踩过的坑

烧录地址错误,症状千奇百怪,但根源往往就一个:地址不匹配。下面是我整理的“烧录地址错误症状-原因-解决方案”速查表,附上真实项目中的排查心路。

5.1 症状:程序完全不运行,串口无任何输出,J-Link识别芯片但无法halt

  • 可能原因:烧录地址填错,导致向量表(复位向量)未写入正确位置,CPU复位后取到0xFFFFFFFF或随机垃圾数据,进入HardFault。
  • 排查思路
    1. 用J-Link Commander执行mem32 0x08000000 4,检查前4字节是否为有效的MSP(通常0x2000xxxx)和Reset Handler(0x0800xxxx)。
    2. 如果全是0xFFFFFFFF,说明Flash未擦除或烧录失败;如果全是0x00000000,说明烧录地址完全错误,数据被写到了别处。
  • 独家技巧:在Keil里,勾选“Options for Target” -> “Debug” -> “Load Application at Startup”,然后在“Utilities” -> “Settings” -> “Flash Download”里,点击“Add”添加Flash算法后,右键该算法选择“Edit”,在弹出的窗口里能看到“Base Address”和“Size”。这个Base Address就是你必须填的烧录地址。很多新手忽略这一步,直接在烧录对话框里乱填。

5.2 症状:程序能启动,但中断不触发,或定时器中断频率严重偏差

  • 可能原因:向量表地址正确,但向量表偏移寄存器(VTOR)未设置,或设置错误。CPU从0x08000000取到了向量表,但你的代码把向量表放在了0x08001000,而VTOR仍指向0x08000000。
  • 排查思路
    1. 在GDB中执行p/x $vtor,查看VTOR寄存器值。它应该等于你的向量表起始地址(通常是0x08000000,除非你做了重定位)。
    2. 检查startup文件,确认是否有SCB->VTOR = 0x08000000;这一行,并且它在SystemInit()之后、main()之前执行。
  • 独家技巧:在STM32CubeMX生成的工程中,SystemInit()函数里有一行HAL_Init();,而HAL_Init()内部会调用HAL_NVIC_SetPriorityGrouping(),但不会设置VTOR。VTOR的设置是在main()函数开头的MX_GPIO_Init();等之前,由SystemCoreClockUpdate();之后的代码完成的。如果你手动修改了向量表地址,必须在main()最开头就设置VTOR。

5.3 症状:ESP32烧录后,串口打印“waiting for download”,然后卡死

  • 可能原因:分区表(partition-table.bin)烧录地址错误。bootloader在0x6000找不到有效的分区表,就认为Flash损坏,进入等待串口下载模式。
  • 排查思路
    1. esptool.py read_flash 0x6000 0x1000 partition_table.bin,读取0x6000地址的1KB数据。
    2. 用十六进制编辑器打开partition_table.bin,查看前4字节是否为EC 00 00 00(这是ESP32分区表的魔数)。
  • 独家技巧:在ESP-IDF项目中,idf.py build生成的build/partition_table/partition-table.bin,其默认烧录地址就是0x6000。但如果你用idf.py -p COMx -b 921600 flash命令,它会自动烧录bootloader(0x1000)、partition-table(0x6000)和app(由分区表定义)。如果你手动用esptool.py烧录,必须严格按照这个顺序和地址执行,缺一不可。我曾因先烧了app再烧partition-table,导致bootloader读到一个“半成品”分区表,直接崩溃。

5.4 症状:STC单片机烧录后,程序运行几秒就死

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询