STM32使用incbin导入Bin音频文件至外部Flash时Hex无数据问题求解
Hey there! I’ve dealt with this exact issue when working on STM32 projects that store audio files in external flash, so let’s break down the fixes step by step:
Root Cause
When you use incbin without explicit section configuration, your compiler/linker will stuff the audio data into default internal flash sections (like .data or .rodata). But if you’re targeting external flash, you need to tell the linker to place this data in a dedicated section mapped to your external flash address—and make sure the hex generation tool includes this section.
Step 1: Update Your Linker Script (.ld)
First, modify your linker script to define a memory region for your external flash and a corresponding section for your audio data.
For example, add this to your .ld file (adjust the origin and length to match your external flash specs—QSPI flash on STM32 is often mapped to 0x90000000):
MEMORY { /* Keep your existing FLASH (internal) and RAM definitions here */ EXT_FLASH (rx) : ORIGIN = 0x90000000, LENGTH = 16M /* Match your external flash size */ } SECTIONS { /* Keep all your existing sections (.text, .data, .bss, etc.) here */ /* Add a dedicated section for external flash data */ .ext_flash_data : { . = ALIGN(4); *(.ext_flash_data) /* Catch all symbols assigned to this section */ . = ALIGN(4); } > EXT_FLASH /* Map this section to the EXT_FLASH memory region */ }
Step 2: Assign Your incbin Data to the New Section
In your C code, explicitly tell the compiler to place the audio data in the .ext_flash_data section using GCC attributes:
// For GCC-based toolchains (STM32CubeIDE, etc.) const uint8_t audio_data[] __attribute__((section(".ext_flash_data"))) = { #incbin("audio.bin") }; // If you're using Keil MDK, use this syntax instead: // const uint8_t audio_data[] __attribute__((section("ext_flash_data"))) = { // #incbin("audio.bin") // };
Make sure the section name matches exactly what you defined in the linker script—case matters!
Step 3: Generate Hex Including the External Flash Section
By default, tools like objcopy only include standard sections (.text, .data) in the hex file. You need to explicitly include your new .ext_flash_data section.
If you’re using a GCC-based build system, update your objcopy command to:
arm-none-eabi-objcopy -O ihex -j .text -j .data -j .ext_flash_data your_project.elf your_project.hex
For Keil MDK:
- Go to your project settings →
Outputtab - Check
Create HEX File - Click
Editnext to it, then add--keep .ext_flash_data*to theAdditional Optionsfield to include the section.
Step 4: Verify the Fix
- Recompile your project and check the
.mapfile—you should seeaudio_datalisted under the.ext_flash_datasection, mapped to your external flash address. - Open the generated
.hexfile with a hex editor, and cross-reference the first few bytes ofaudio.binto confirm the data is present.
Common Pitfalls to Avoid
- Double-check your external flash origin address: STM32 uses different memory ranges for QSPI vs FMC-connected flash (e.g., FMC NOR flash might be
0x60000000). - Ensure the section name in your C code and linker script are identical—typos here are a frequent culprit.
- If you’re using a bootloader, make sure it doesn’t overwrite the external flash region where your audio data is stored.
内容的提问来源于stack exchange,提问作者vel murugan

