--
You received this message because you are subscribed to the Google Groups "NuttX" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nuttx+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nuttx/6d06f2f1-78a0-4aa0-f902-4cba7f96049a%40gmail.com.
--
You received this message because you are subscribed to the Google Groups "NuttX" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nuttx+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nuttx/037894ef-238a-fc5a-3d1b-4866e9cbc043%40gmail.com.
I would like to ask for advice. I am facing a problem of understanding for exactly to update the firmware of a XIP flash memory. My idea so far is to. define 2 regions in the flash memory with equal size. Active region from which the code is currently executed and "update" region in which the new firmware will be uploaded and after it is uploaded the CPU will be reconfigured to start executing the firmware for the updated region.
That is a pretty standard strategies. It protects against a bad download bricking the device.
There has to be a small, third region that just contains some housekeeping information like which flash region has the bootable image and to execute that image. A partition could (1) have not valid image, (2) have an unverified image, or (3) have a verified image.
I there is an unverified image, the boot-up logic should mark
that as "not valid" then execute it. When it runs, it should
change its state to verified. Subsequently, the boot-up logiv
should revert to the verified image.
The problem is i dont understand how to write/erase sectors in flash memory which is used as a XIP memory. The only possible solution which i see so far is to define all write/erase function to be placed and executed from the RAM memory. Can you please give me advice am i on the right direction or give me some advice how to deal with that issue?
I don't think I fully understand your concerned. If flash image A is running in partition 1, it does not need to execute out of RAM to write flash image B in partition 2.
Is the concern because you cannot execute from this flash memory while modifying it? If the hardware behaves that way, then yes, you would have to execute from RAM.
If you have plenty of external RAM, the perhaps the proper solution is to always execute entirely from RAM. Otherwise, you can use ramfuncs to move some of the functions into RAM at bootup. Look in imxrt_start.c:
335 /* Copy any necessary code sections from FLASH to RAM. The correct
336 * destination in OCRAM is given by _sramfuncs and _eramfuncs. The
337 * temporary location is in flash after the data initialization code
338 * at _framfuncs. This should be done before imxrt_clockconfig() is
339 * called (in case it has some dependency on initialized C variables).
340 */
341
342 #ifdef CONFIG_ARCH_RAMFUNCS
343 for (src = &_framfuncs, dest = &_sramfuncs; dest < &_eramfuncs; )
344 {
345 *dest++ = *src++;
346 }
347 #endif
And at, for example, imxrt1060-evk/scripts/flash-ocram.ld:
169 .ramfunc ALIGN(4):
170 {
171 _sramfuncs = ABSOLUTE(.);
172 *(.ramfunc .ramfunc.*)
173 _eramfuncs = ABSOLUTE(.);
174 } > sram AT > flash
175
176 _framfuncs = LOADADDR(.ramfunc);
That is all you need to use to execute functions from RAM.
Greg
...you can use ramfuncs to move some of the functions into RAM at bootup. Look in imxrt_start.c:
335 /* Copy any necessary code sections from FLASH to RAM. The correct
336 * destination in OCRAM is given by _sramfuncs and _eramfuncs. The
337 * temporary location is in flash after the data initialization code
338 * at _framfuncs. This should be done before imxrt_clockconfig() is
339 * called (in case it has some dependency on initialized C variables).
340 */
341
342 #ifdef CONFIG_ARCH_RAMFUNCS
343 for (src = &_framfuncs, dest = &_sramfuncs; dest < &_eramfuncs; )
344 {
345 *dest++ = *src++;
346 }
347 #endif
And at, for example, imxrt1060-evk/scripts/flash-ocram.ld:
169 .ramfunc ALIGN(4):
170 {
171 _sramfuncs = ABSOLUTE(.);
172 *(.ramfunc .ramfunc.*)
173 _eramfuncs = ABSOLUTE(.);
174 } > sram AT > flash
175
176 _framfuncs = LOADADDR(.ramfunc);
That is all you need to use to execute functions from RAM.
I don't see any usage of ramfuncs in the i.MXRT code, but there
are examples for other architectures. They all work the same. It
looks like other MCUs have issues about running from FLASH and
modifying FLASH concurrently too:
src/efm32/efm32_flash.c:#ifndef CONFIG_ARCH_RAMFUNCS
src/efm32/efm32_flash.c:int __ramfunc__ msc_load_verify_address(uint32_t *address)
src/efm32/efm32_flash.c:int __ramfunc__ msc_load_write_data(uint32_t *data, uint32_t num_words,
src/efm32/efm32_flash.c:ssize_t __ramfunc__ up_progmem_eraseblock(size_t block)
src/efm32/efm32_flash.c:ssize_t __ramfunc__ up_progmem_write(size_t addr, const void *buf, size_t size)
./src/samv7/sam_eefc.c:#if defined(CONFIG_ARCH_HAVE_RAMFUNCS) && defined(CONFIG_ARCH_RAMFUNCS)
./src/samv7/sam_eefc.c:__ramfunc__ void sam_eefc_writefmr(uint32_t regval)
./src/samv7/sam_eefc.c:__ramfunc__ int sam_eefc_command(uint32_t cmd, uint32_t arg)
./src/samv7/sam_eefc.c:__ramfunc__ int sam_eefc_readsequence(uint32_t start_cmd, uint32_t stop_cmd,
./src/samv7/sam_eefc.c:#endif /* defined(CONFIG_ARCH_HAVE_RAMFUNCS) && defined(CONFIG_ARCH_RAMFUNCS) */
There are some platforms that have to use RAM functions to perform flash clock configuration too.
For ARM, __ramfunc__ is defined in:
src/common/up_internal.h:# define __ramfunc__ __attribute__ ((section(".ramfunc"),long_call,noinline))
Greg
--
You received this message because you are subscribed to the Google Groups "NuttX" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nuttx+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nuttx/b2af0c45-ad9d-3766-be4c-48f60f3bd59c%40gmail.com.