Prevent sector flash erase on program/debug

Sysprogs forums Forums VisualGDB Prevent sector flash erase on program/debug

Tagged: 

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #20382
    chris250
    Participant

    Hi,

    I am using the latest version of VisualGDB Embedded with a STM32F476. I am using various sectors of the STM32F746 internal flash for my program, including a bootloader, 2 sectors for EEPROM emulation, some unused sectors, and finally the local of the program code.
    When running debug on the STM32F746 from VisualGDB, I would like to configure it so that it does not erase the sectors used for EEPROM emulation. Is there something I can add to the LDS file to achieve this? If not, is there another way of preventing VisualGDB from erasing particular sectors on flashing/debug?

    Thanks in advance guys.

    #20386
    support
    Keymaster

    Hi,

    Normally OpenOCD should be able to figure out the correct sectors to erase automatically. So our first advice would be to double-check what addresses are actually used by various sections of your program. Please try running arm-eabi-objdump -h <ELF file> and check what section covers the address that is erased and what attributes are set to it. If it has the LOAD attribute, you would need to mark it with the noload attribute in the linker script file.

     

    #20398
    chris250
    Participant

    Hi,

    I have modified my linker script and used arm-eabi-objdump -h <ELF file> to inspect the sections used.

    It lists the following LMA addresses

    • bootloader at 0x08000000
    • .isr_vector, .text and other program sections at 0x08040000 +
    • RAM objects to be loaded at boot at 0x08040d4b0 +

    There is nothing in between the end of the bootloader code in the first sector (0x08000000), and the beginning of the program code (the ISR vector table) at 0x08040000.

    Still, when I right click on the Visual Studio project and choose Program and Start Without Debugging I always see the following messages in the openocd output:

    Info: Erasing FLASH: 0x08000000-0x08080000...
    ...
    Info: Erasing FLASH: 0x08040000-0x08080000...

    The project has got an embedded binary for its bootloader, which I created using the guide on this website. It is like openocd is treating the bootloader (0x08000000) plus the application (0x08040000) as one large blob that it needs to program, even though there is nothing in between the bootloader and the application.

    Is there a way to configure this so that it doesn’t erase the sectors in between the bootloader and the application? That is where my EEPROM is located…

    Thanks again for your help.

    • This reply was modified 6 years, 8 months ago by chris250.
    #20463
    support
    Keymaster

    Hi,

    This looks like something specific to the OpenOCD FLASH erasing logic. Although this is normally not covered by our support (please consider using Segger J-Link if you are looking for a debug probe that just works out-of-the-box and comes with its own support), we have published a detailed tutorial showing how to build our OpenOCD fork from scratch and debug it with VisualGDB: https://visualgdb.com/tutorials/arm/openocd/build/

    Please ensure you use the following VisualGDB build: http://sysprogs.com/files/tmp/VisualGDB-5.4.1.2094.msi

    This should help understand why OpenOCD decides to merge the 2 erase regions and tweak it if necessary.

    #20562
    chris250
    Participant

    Hi,

    Thank you for your reply and thank you for writing the guide. When I have finished this current project I will do some debugging and post any findings back here.

    In the mean time, I have edited the linker file to say that the flash begins at 0x08040000 (where my application should be) and removed the embedded binary for the bootloader. That way I can still debug the application without openOCD erasing the sectors inbetween the bootloader and the application.

    The OpenOCD guide does mention sector erasing, specifically:

    Command: flash write_image [erase] [unlock] filename [offset] [type]
    Write the image filename to the current target’s flash bank(s). Only loadable sections from the image are written. A relocation offset may be specified, in which case it is added to the base address for each section in the image. The file [type] can be specified explicitly as bin (binary), ihex (Intel hex), elf (ELF file), s19 (Motorola s19). mem, or builder. The relevant flash sectors will be erased prior to programming if the erase parameter is given. If unlock is provided, then the flash banks are unlocked before erase and program. The flash bank to use is inferred from the address of each image section.

    Warning: Be careful using the erase flag when the flash is holding data you want to preserve. Portions of the flash outside those described in the image’s sections might be erased with no notice.

    When a section of the image being written does not fill out all the sectors it uses, the unwritten parts of those sectors are necessarily also erased, because sectors can’t be partially erased.
    Data stored in sector “holes” between image sections are also affected. For example, “flash write_image erase …” of an image with one byte at the beginning of a flash bank and one byte at the end erases the entire bank – not just the two sectors being written.
    Also, when flash protection is important, you must re-apply it after it has been removed by the unlock flag.

    This does say that the data inbetween sectors will be affected. I spent 10 minutes looking through the source for OpenOCD, and in openocd/src/flash/nor/core.c the following function is used to erase the flash:

    /* Manipulate given flash region, selecting the bank according to target
     * and address. Maps an address range to a set of sectors, and issues
     * the callback() on that set ... e.g. to erase or unprotect its members.
     *
     * Parameter iterate_protect_blocks switches iteration of protect block
     * instead of erase sectors. If there is no protect blocks array, sectors
     * are used in iteration, so compatibility for old flash drivers is retained.
     *
     * The "pad_reason" parameter is a kind of boolean: when it's NULL, the
     * range must fit those sectors exactly. This is clearly safe; it can't
     * erase data which the caller said to leave alone, for example. If it's
     * non-NULL, rather than failing, extra data in the first and/or last
     * sectors will be added to the range, and that reason string is used when
     * warning about those additions.
     */
    static int flash_iterate_address_range_inner(struct target *target,
     char *pad_reason, uint32_t addr, uint32_t length,
     bool iterate_protect_blocks,
     int (*callback)(struct flash_bank *bank, int first, int last))
    
    

    This function basically starts at the first address and finds the sector range for the entire binary being programmed. In my case with the combined bootloader/application binary, that will span the sectors containing the EEPROM.

    • This reply was modified 6 years, 8 months ago by chris250.
    • This reply was modified 6 years, 8 months ago by chris250.
    #20569
    support
    Keymaster

    Hi,

    Thanks for checking this. Looks like the only reasonable way to prevent OpenOCD from erasing those sectors would be to patch its source code. Another option would be to try Segger J-Link. Unlike the community-maintained OpenOCD, their gdb stub is covered by their support, so unless they already have an option for selective erase, they might be able to add it for you.

Viewing 6 posts - 1 through 6 (of 6 total)
  • You must be logged in to reply to this topic.