Software download without using bootloader.


To be able to update our software at the field, we would like to download the new software to RAM and overwrite the current program.

This is the way that we always do (probably everyone else too) using the other Renesas processors including RX series.

As the hardware is concerned, in our project, the only way to update the software via backplane from another board using RS232.

We don't want to use the bootloader solution. We want to run the code flash update software in RAM and update the software from address 0 for S7G2 processor.

Our application program is not big about 120 KBytes and it can be downloaded to RAM easily. I am only using HAL functions and no RTOS.

I am using r_flash_hp stack but what I found is; the erase function runs in RAM, as they claim, but unfortunately it still accesses to flash.

In this particular project, you could erase Block 0, 1 but when it comes to Block 2 it crashes.

I stopped all the interrupts and I debugged it and found that HW_FLASH_HP_pe_mode_exit() (still in RAM) makes a call to R_BSP_CacheSet(p_ctrl->cache_state) which is in flash area. Erasing Block 2 deletes the area where R_BSP_CasheSet is located and then when you make this
call, it crashes naturally.

I am very surprised that a module which supposed to be running from RAM makes a reference to code flash area and it looks like a BUG to me. (note that all the interrupts disabled).

I have read all the flash update related correspondences in this forum and as far as I understand, because of this bug (or may be there is a reason),
you are only suggesting bootloader solution.

I did a test, by copying the whole project to RAM but I couldn't run it, it crashes somewhere at the startup. Not a acceptable solution for us anyway.

Is there any way to get around this problem such as, is there a way to copy just BSP related code to RAM as well. I don't know
how to do that. That might be the solution since we can not change the SSP code. Is there a linker solution?

BTW, I wrote a bootloader for this project and it works but no one (upper management) likes it and it could be a show stopper for us.

Really bad after spending months building the hardware and developing the software. I am using SSP 1.6.0 and e2Studio.

Your help is really appreciated. Even if you say officially it is impossible to do that is very helpful since we stop spending more unnecessary time..


  • We should have highlight this : hal modules are dependent on BSP. If you remove/modified the BSP, you will most likely crash. In the usage scenario you presented, those bsp codes called by r_flash_hp must also be shifted to RAM, including the vector table. Your new application may have a different set of vector numbers assigned.

    I suppose your current application is able to secure enough RAM and download the new firmware (120k) on to RAM. Does it have enough space for code to do flashing? You can compile this "flasher" code entirely to run in RAM. Your current application will jump to the flasher (it has its own BSP and r_flash_hp, but all in RAM). The flasher will erase flash rom and write the new firmware to flash rom.
    Note that if your board loses power during flashing, you need to prepare alternate method of programming. That why we suggest bootloader and it always stay and can recover from such issues.

    What do you think?
  • Hi CS Yep,

    Thanks for the response. I agree, somehow I have to move BSP related code to RAM but my question was how can I do that. 

    To demonstrate the problem I have created a project based on " r11an0087eu0120-synergy-flash-hal-mod-guide " project, using Flash_HP_MG_AP. This is a simplest project that trying to erase all the area the project covers. The project sits on from Block0 to BlockX. I have changed the code so I am tring to erase block0 to block3.

    r_flash_hp/Erase() function itself is in RAM but in one stage as shown in the following figures it accesses the BSP CacheSet routine inside the flash in block 2. 

    I have changed the function  code_flash_operations to

    __attribute__((section(".code_in_ram"))) void code_flash_operations() so that it runs in RAM.

    Above snapshots were taken while it was erasing block 0 and 1 but when it comes to block 2 it erases the block ( from 0x4000 to 0x5FFF) and then since R_BSP_CacheSet() is in 0x4510 it goes to gagaland ..

    As I said, I don't know how BSP related code can also be transferred to RAM. You said it is possible so could you please tell me how. 

    Since we can't modify SSP/BSP code, it can't be set to RAM inside the program area but how can you change the linker script to make that happen. I am still trying to learn how linker script works and I am not very good at it.

    Also, yes you are right there is a possibility of major fail if power is lost during erase/write process using this method. Unfortunately, we are very aware of that.


  • Have a look at the attached project, using the linker script I have moved the contents of the file synergy/ssp/src/bsp/mcu/s7g2/bsp_cache.c to run from RAM:-

                    0x1ffe17e4       0x28 ./synergy/ssp/src/bsp/mcu/s7g2/bsp_cache.o
                    0x1ffe17e4                R_BSP_CacheOff
                    0x1ffe180c       0x40 ./synergy/ssp/src/bsp/mcu/s7g2/bsp_cache.o
                    0x1ffe180c                R_BSP_CacheSet
                    0x1ffe184c                __BSP_CacheIn_RAM_End = .


    There is a slight complication that the startup code of the SSP uses the function R_BSP_CacheSet() before the C runtime environment has been fully initialised (i.e. the initialised data has not been copied from ROM to RAM, and that is where the  .code_in_ram section is copied). So I have put the contents of bsp_cache.c in it's own section and added some code to copy the contents of this section from ROM to RAM in the file src\R_BSP_Warmstart.c.


  • Hi Jeremy,

    Thanks for the quick response. It was very helpful and I learned a lot.

    I have implemented your suggestions to my test project and I have moved on until to the next hurdle. I came across quite a few more places that R_Flash_HP software accesses to flash. I have started to add more and more functions to move to the RAM list but I am sure there must be better way of doing it. 

    The latest hurdle was inside flash get block info where HW_FLASH_HP_erase_next_block() function accesses g_flash_code_region.p_block_array[i] which is inside Flash area as a const array. (const uint32_t g_fmi_data[] ).  I couldn't move that.. 

    I have spent quite a bit time to figure out how to move bsp related stuff to RAM but I was unsuccessful.

    I have inserted my test project. If I am able to erase all the blocks where the current software occupies then I can update the software without using a bootloader. I am currently stuck in erasing Block2 where the most bsp related code is stored. Any suggestion will be very helpful.

    I am testing this project using SK_S7G2 board. I am using E2Stduio. 

    Thanks again.

  • To get it all to work, the flash driver has to be edited to remove the static declaration of g_flash_code_region, so the information that is in flash can be copied to RAM.

    I excluded the file synergy/ssp/src/driver/r_flash_hp/r_flash_hp.c from the build :-

    and copied the file to the src/ directory to make the change.

    Then the information in g_flash_code_region.p_block_array is copied to RAM :-


    flash_fmi_block_info_t     block_array[2];

        /* Copy the information that is in flash to RAM */
        for (uint32_t i = 0; i < g_flash_code_region.num_regions; i++)
            block_array[i].block_section_end_addr = g_flash_code_region.p_block_array[i].block_section_end_addr;
            block_array[i].block_section_st_addr  = g_flash_code_region.p_block_array[i].block_section_st_addr;
            block_array[i].block_size             = g_flash_code_region.p_block_array[i].block_size;
            block_array[i].block_size_write       = g_flash_code_region.p_block_array[i].block_size_write;

        g_flash_code_region.p_block_array = &block_array[0];

    Also, the instance structure is in flash, so the Flash API and control structure have to be accessed directly :-

        err = R_FLASH_HP_Erase( &g_flash0_ctrl, FLASH_CF_8KB_BLOCK0, 1);
        if(err != SSP_SUCCESS)
            error_trap("g_flash0.p_api->erase", err);


  • Hi Jeremy,

    That is it. It works. 

    I didn't know that a SSP file can be excluded and moved to the src area. That is a big trick.

    I think, if anyone wants to update their software without using a bootloader can use your project file as a reference. 

    Just import the project and build all.. Test it with your evaluation board .. in this case SK_S7G2. 

    Note that, whoever is considering this method should know that during this process, while only in erasing and writing period ( keep it short!! ), if power goes down on the board you will have a brick.

    Good thing is you don't have to worry about bootloader software maintenance or jumping to the application problems.


    Thanks a lot.

  • Would it be possible to move the instance structure into ram so that the api could still be used?

  • Hi Jeremy,

    I have found a strange problem in block_array update part. The above code only updates g_flash_code_region but g_flash_data_region should be moved to RAM as well if you don't want to change r_flash_hp.c file.

    extern flash_fmi_regions_t g_flash_code_region;
    extern flash_fmi_regions_t g_flash_data_region;
    flash_fmi_block_info_t block_array[2];
    flash_fmi_block_info_t block_data_array[2];


    for (i = 0; i < g_flash_code_region.num_regions; i++)
    block_array[i].block_section_end_addr = g_flash_code_region.p_block_array[i].block_section_end_addr;
    block_array[i].block_section_st_addr = g_flash_code_region.p_block_array[i].block_section_st_addr;
    block_array[i].block_size = g_flash_code_region.p_block_array[i].block_size;
    block_array[i].block_size_write = g_flash_code_region.p_block_array[i].block_size_write;

    g_flash_code_region.p_block_array = &block_array[0];

    for (i = 0; i < g_flash_data_region.num_regions; i++)
    block_data_array[i].block_section_end_addr = g_flash_data_region.p_block_array[i].block_section_end_addr;
    block_data_array[i].block_section_st_addr = g_flash_data_region.p_block_array[i].block_section_st_addr;
    block_data_array[i].block_size = g_flash_data_region.p_block_array[i].block_size;
    block_data_array[i].block_size_write = g_flash_data_region.p_block_array[i].block_size_write;

    g_flash_data_region.p_block_array = &block_data_array[0];

    The reason is, there is a problem in r_flash_hp.c / flash_get_block_info() function. This function finds out whether the Sector start address belongs to Code Flash or Data Flash area.

    If a new program is being written into one sector with  g_flash_data_region information, when the next sector address is checked, it will read a random values for g_flash_data_region data. Depending on that random data, new sector data could be filled with data flash information instead of code flash info. Eventually next sector writing will return with error and the program is completely lost..

    As an example, In our project, our program size is about 130 Kbytes and goes up to Sector 10. Incidentally, g_flash_data_region variable was located in Sector 9.

    During the new version software update, all the Sectors are erased and written Sector by Sector and after Sector 9 is written and try to write in to Sector 10,  flash_get_block_info() tries to get Sector 10 information by using Sector 10 start address. Inside the function, it reads random Data Flash info because it still points to the old software g_flash_data_region location inside newly written Sector 9 data. Depending on the random values that it reads, it may accept the Sector 10 address as Data Flash address and fills with wrong values. ( Note; it happened to us) 

    Basically, if g_flash_data_region is pointing to a sector which has already been written and more sector needs to be written, program may have problems writing to the other sectors.  

    Other than that it works. Thanks again for your help.