Showing results for 
Search instead for 
Did you mean: 

Update firmware from W25Qxx flash

Associate II

I use a board with STM32F405 + W25Qxx. At the moment, I have implemented downloading the firmware file to an external flash memory (via CAN). The process of downloading and verification is implemented in the main firmware. It is necessary to implement overwriting the firmware from the external flash memory, and the following reboot


Make a Loader that lives in the first 16KB sector that can read the W25Qxx and manage the erase and update of the Application which now starts at 0x08004000.

Don't initiate the Loader until you have a complete and validated image in the external flash.

In usual operation the Loader transfers control to the Application. The Loader is always present, doesn't erase itself, and perhaps offers other recovery modes via CAN and UART

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I use IAR compiler, can you help me adapt this 
How to add Header memory region in IAR?

Not using IAR, would suspect it would get done in the .ICF file, the equivalent to the Linker Script / Scatter File methods used by other tools.

Still, probably easier just to embedded the image length in a spare vector, and append the CRC on the end. I've shown how this is done in Keil multiple times on the forum.

Perhaps review IAR's documentation, or work with your support contact there, with regards to the CRC methods and application they support directly.

You can also just write C applications with STDIO file handling and manage the packaging yourself as a post-link step.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

My icf file.

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
define symbol __ICFEDIT_intvec_start__ = 0x08020400;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_HEADER_start__ = 0x08020000;
define symbol __ICFEDIT_region_HEADER_end__   = 0x080203FF;
define symbol __ICFEDIT_region_ROM_start__    = 0x08020400;
define symbol __ICFEDIT_region_ROM_end__      = 0x080FFFFF;
define symbol __ICFEDIT_region_RAM_start__    = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__      = 0x2001FFFF;
define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000;
define symbol __ICFEDIT_region_CCMRAM_end__   = 0x1000FFFF;
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__   = 0x200;
/**** End of ICF editor section. ###ICF###*/

define memory mem with size = 4G;
define region ROM_region      = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region RAM_region      = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];
define region CCMRAM_region   = mem:[from __ICFEDIT_region_CCMRAM_start__   to __ICFEDIT_region_CCMRAM_end__];

define region HEADER_region	  = mem:[from __ICFEDIT_region_HEADER_start__ to __ICFEDIT_region_HEADER_end__];

define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

initialize by copy { readwrite };
do not initialize  { section .noinit };

place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

place in ROM_region   { readonly };
place at address mem:__ICFEDIT_region_HEADER_start__ {readonly section .fw_header};
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };


I also add in my main.c such  code

#define IMAGE_OFFSET        0x200             //because vector table offset should be a multiple of 0x200

typedef struct __attribute__((packed)){
    uint16_t image_magic;
    uint16_t image_version;
    uint32_t image_size;
    uint32_t crc;

} image_hdr_t;

image_hdr_t image_hdr __attribute__((section(".fw_header")))= {
    .image_magic = IMAGE_MAGIC,
    .image_version = 9,
    .image_size = 0,               //to be added manually using script after build
    .crc = 0                       //-do-

After compile I see in map file

"A0":  place at address 0x802'0400 { ro section .intvec };
"P1":  place in [from 0x802'0400 to 0x80f'ffff] { ro };
define block CSTACK with size = 1K, alignment = 8 { };
define block HEAP with size = 512, alignment = 8 { };
"P2":  place in [from 0x2000'0000 to 0x2001'ffff] {
          rw, block CSTACK, block HEAP };
initialize by copy { rw };

No sections matched the following patterns:

  ro section .fw_header  in "A1"