EFL internal flash driver on single bank MCU

This forum is dedicated to feedback, discussions about ongoing or future developments, ideas and suggestions regarding the ChibiOS projects are welcome. This forum is NOT for support.
User avatar
alex31
Posts: 418
Joined: Fri May 25, 2012 10:23 am
Location: toulouse, france
Has thanked: 53 times
Been thanked: 81 times

EFL internal flash driver on single bank MCU

Postby alex31 » Fri Jul 25, 2025 10:39 am

Hello,

I have to write a bootloader able to flash the application (from external SPI eeprom) on a stm32g491 (512Kb, single bank).
from what I have understood, most of the bootloader code can reside in flash, but the part that actually erase and program the flash should run from RAM since one bank devices does not permit 'read while write' and programming the flash will stall the program.

It means some magic incantation in the linker file, a routine that copy the function from flash to ram, blocking IT when the RAM function is running.

Is the EFL driver aware of that and can be used for my use case ?

Alexandre

User avatar
Giovanni
Site Admin
Posts: 14704
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1146 times
Been thanked: 960 times

Re: EFL internal flash driver on single bank MCU

Postby Giovanni » Fri Jul 25, 2025 11:38 am

Hi,

Startup files can copy code in RAM but the EFL driver would need an extra information: the linker section name where the code should be copied (could be a configuration).

Giovanni

User avatar
alex31
Posts: 418
Joined: Fri May 25, 2012 10:23 am
Location: toulouse, france
Has thanked: 53 times
Been thanked: 81 times

Re: EFL internal flash driver on single bank MCU

Postby alex31 » Fri Jul 25, 2025 2:38 pm

I will give a try, I will decorate the EFL api and lld functions with a macro that can be nothing or an attribute section.
should I also decorate the functions declared inline ? If they are really inlined, there should be no need, but I dont't know if inline is only a hint or an order that the compiler must follow ?

User avatar
Giovanni
Site Admin
Posts: 14704
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1146 times
Been thanked: 960 times

Re: EFL internal flash driver on single bank MCU

Postby Giovanni » Fri Jul 25, 2025 2:50 pm

You should use portability macros, no compiler-specific code into the drivers.

Giovanni

User avatar
alex31
Posts: 418
Joined: Fri May 25, 2012 10:23 am
Location: toulouse, france
Has thanked: 53 times
Been thanked: 81 times

Re: EFL internal flash driver on single bank MCU

Postby alex31 » Sat Jul 26, 2025 10:46 am

Some information on flash memory I discovered while experimenting with the STM32G4 and ChibiOS:

The EFL module is designed around MFS use cases and relies on a VMT-based API, which is not suitable for direct flash operations. So if you need to use flash for anything other than a filesystem, you’ll have to go through the LLD API.

Using the portability macro to place the flash programming function in RAM works well, but only if you also protect the write loop with chSysLock()/chSysUnlock(). Without that, any interrupt that occurs during programming may try to execute ISR code still in flash, which causes the system to stall until the flash operation completes.

Performance gain: writing a 2KB page went from 24 ms down to 1 ms (24× improvement) when stm32_flash_enable_pgm() is placed in RAM.

This gain isn’t very useful for MFS (which typically writes small chunks), but for a bootloader performing IAP, it’s a big deal.

I’ve also implemented fast programming mode (writing 256 bytes in a row), but it only works after a mass erase. This implies the entire bootloader must run from RAM. That means embedding the full bootloader as data within the main application, copying it to RAM, and jumping to it when needed.

Does anyone have suggestions or best practices for embedding and executing a complete application from RAM (not just a few functions) on STM32?

I have included the patch which is dead simple for the test, if included it will need more work for all the architecture, the documentation of HAL_EFL_SECTION_HOOK macro, etc.

In mcuconf, I added :

Code: Select all

#define HAL_EFL_SECTION_HOOK __attribute__((section(".ram4_init"), noinline, long_call))

Alexandre
Attachments
efl_ram.patch.zip
(822 Bytes) Downloaded 74 times

User avatar
Giovanni
Site Admin
Posts: 14704
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1146 times
Been thanked: 960 times

Re: EFL internal flash driver on single bank MCU

Postby Giovanni » Wed Jul 30, 2025 7:04 pm

Hi,

Why the API is not suitable for direct flash operations? it should be quite generic, it is not meant for MFS only.

Giovanni

User avatar
alex31
Posts: 418
Joined: Fri May 25, 2012 10:23 am
Location: toulouse, france
Has thanked: 53 times
Been thanked: 81 times

Re: EFL internal flash driver on single bank MCU

Postby alex31 » Thu Jul 31, 2025 6:07 pm

Why the API is not suitable for direct flash operations? it should be quite generic, it is not meant for MFS only.


Hello,
Is there more that these functions in the generic API ?

Code: Select all

/*===========================================================================*/
/* External declarations.                                                    */
/*===========================================================================*/

#ifdef __cplusplus
extern "C" {
#endif
  void  eflInit(void);
  void  eflObjectInit(EFlashDriver *eflp);
  msg_t eflStart(EFlashDriver *eflp, const EFlashConfig *config);
  void  eflStop(EFlashDriver *eflp);
#ifdef __cplusplus
}
#endif


For my use case, I also need generic API that wrap these lld functions :

Code: Select all

 flash_error_t efl_lld_read(void *instance, flash_offset_t offset,
                             size_t n, uint8_t *rp);
  flash_error_t efl_lld_program(void *instance, flash_offset_t offset,
                                size_t n, const uint8_t *pp);
  flash_error_t efl_lld_start_erase_all(void *instance);
  flash_error_t efl_lld_start_erase_sector(void *instance,
                                           flash_sector_t sector);
  flash_error_t efl_lld_query_erase(void *instance, uint32_t *msec);
  flash_error_t efl_lld_verify_erase(void *instance, flash_sector_t sector);



I probably missed something :-)
Alexandre

User avatar
Giovanni
Site Admin
Posts: 14704
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1146 times
Been thanked: 960 times

Re: EFL internal flash driver on single bank MCU

Postby Giovanni » Thu Jul 31, 2025 6:37 pm

Hi,

Yes, the functions are not in that module, you need to look into the flash interface, those functions work on any flash of any kind.

Giovanni


Return to “Development and Feedback”

Who is online

Users browsing this forum: No registered users and 129 guests