You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32-S3汇编代码编译烧录失败问题排查求助

ESP32-S3 汇编代码无法启动问题排查

操作步骤

  1. 汇编代码 pin15.S:
.section .text
    .global _start

    _start:
        movi a2, 0x3FF44000
        movi a3, 1 << 15
        s32i a3, a2, 0x4      # Set output bit for GPIO 15
    loop:
        movi a2, 0x3FF44000
        movi a3, 1 << 15
        s32i a3, a2, 0x4
        call0 delay
        movi a2, 0x3FF44000   # GPIO base address
        movi a3, 1 << 15      # Mask for GPIO 15
        s32i a3, a2, 0x8      # Clear output bit for GPIO 15
        call0 delay
        j loop
    delay:
        movi a1, 0x3FFFFF
    delay_loop:
        addi a1, a1, -1
        bnez a1, delay_loop
        ret
  1. 编译命令:
xtensa-esp32s3-elf-as -o pin15.o pin15.S
xtensa-esp32s3-elf-ld -T linkerscript2.ld -o pin15.elf pin15.o
  1. 链接脚本 linkerscript2.ld:
ENTRY(_start)
MEMORY
{
iram0_0_seg : ORIGIN = 0x40100000, LENGTH = 0x20000  /* Instruction RAM */
dram0_0_seg : ORIGIN = 0x3FFB0000, LENGTH = 0x20000  /* Data RAM */
}
SECTIONS
{
.literal : {
    *(.literal)
} > iram0_0_seg
.text : {
    *(.text)
    *(.text.*)
} > iram0_0_seg
.data : {
    *(.data)
    *(.data.*)
} > dram0_0_seg
.bss : {
    *(.bss)
    *(.bss.*)
} > dram0_0_seg
}
  1. 镜像生成与烧录命令:
esptool.py --chip esp32s3 elf2image pin15.elf
esptool.py --chip esp32s3 --port /dev/ttyACM0 --baud 115200 write_flash 0x10000 pin15.bin

报错信息

ESP-ROM:esp32s3-20210327
 Build:Mar 27 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
 Saved PC:0x403cdd11
 SPIWP:0xee
 mode:DIO, clock div:1
 load:0x3fce3810,len:0x1798
 load:0x403c9700,len:0x4
 load:0x403c9704,len:0xcbc
 load:0x403cc700,len:0x2d98
 entry 0x403c9914
 I (31) boot: ESP-IDF v5.2-dirty 2nd stage bootloader
 I (31) boot: compile time Aug 5 2024 03:46:49
 I (31) boot: Multicore bootloader
 I (35) boot: chip revision: v0.2
 I (38) boot.esp32s3: Boot SPI Speed : 80MHz
 I (43) boot.esp32s3: SPI Mode : DIO
 I (48) boot.esp32s3: SPI Flash Size : 2MB
 I (53) boot: Enabling RNG early entropy source...
 I (58) boot: Partition Table:
 I (62) boot: ## Label Usage Type ST Offset Length
 I (69) boot: 0 nvs WiFi data 01 02 00009000 00005000
 I (76) boot: 1 otadata OTA data 01 00 0000e000 00002000
 I (84) boot: 2 app0 factory app 00 00 00010000 00140000
 I (91) boot: 3 spiffs Unknown data 01 82 00150000 000a0000
 I (99) boot: End of partition table
 I (103) boot: Defaulting to factory image
 I (108) esp_image: segment 0: paddr=00010020 vaddr=40080000 size=00044h (    68) load
 E (116) esp_image: Segment 0 0x40080000-0x40080044 invalid: bad load address range
 E (124) boot: Factory app partition is not bootable
 E (130) boot: No bootable app partitions in the partition table

排查分析与结论

核心问题根源

报错中的*E (116) esp_image: Segment 0 0x40080000-0x40080044 invalid: bad load address range*是关键。ESP32-S3的二级bootloader尝试将程序加载到0x40080000,但该地址属于MMIO区域,并非合法的IRAM地址。

问题出在镜像生成流程:手动用xtensa-esp32s3-elf-ld链接的ELF文件,没有包含ESP32-S3镜像要求的段元信息,导致esptool.py elf2image无法识别你在链接脚本中指定的0x40100000执行地址,反而默认使用了旧ESP32系列的非法加载地址。

是否需要更换分区表?

不需要。当前分区表的factory分区起始地址0x10000、长度0x140000完全符合规范,问题与分区表无关。

修复方案

  1. 修改链接脚本,添加Flash加载地址属性
    给代码段和数据段指定Flash中的存储地址,让elf2image能正确生成镜像。修改后的链接脚本示例:

    ENTRY(_start)
    MEMORY
    {
      iram0_0_seg : ORIGIN = 0x40100000, LENGTH = 0x20000  /* Instruction RAM */
      dram0_0_seg : ORIGIN = 0x3FFB0000, LENGTH = 0x20000  /* Data RAM */
      flash_code : ORIGIN = 0x00010020, LENGTH = 0x13FFE0  /* Factory分区起始+镜像头偏移 */
    }
    SECTIONS
    {
      .iram0.text : AT(flash_code) {
        _iram_text_start = .;
        *(.text)
        *(.text.*)
        *(.literal)
        _iram_text_end = .;
      } > iram0_0_seg
      .data : AT(flash_code + (_iram_text_end - _iram_text_start)) {
        _data_start = .;
        *(.data)
        *(.data.*)
        _data_end = .;
      } > dram0_0_seg
      .bss : {
        *(.bss)
        *(.bss.*)
      } > dram0_0_seg
    }
    

    其中AT(flash_code)指定了段在Flash中的存储位置,与烧录地址对应。

  2. 用ESP-IDF工具链编译(更可靠)
    手动链接容易踩格式坑,推荐将汇编代码放入ESP-IDF工程:

    • 在工程main目录下添加pin15.S
    • 修改CMakeLists.txt,添加target_sources(app PRIVATE pin15.S)
    • 用idf.py build编译,自动生成符合规范的镜像,再用idf.py flash烧录
  3. 验证ELF段信息
    生成ELF后,执行xtensa-esp32s3-elf-readelf -l pin15.elf查看段信息,确认LOAD段的虚拟地址(VirtAddr)是你指定的IRAM地址,物理地址(PhysAddr)是Flash中的正确偏移。


内容的提问来源于stack exchange,提问作者blurrpp314

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 10:36:00