How to properly write into Flash with FlexSPI NOR API ?

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

How to properly write into Flash with FlexSPI NOR API ?

跳至解决方案
4,573 次查看
paul_guirbal
Contributor II

Hi everyone,

My project is using the RT1064 and I am trying to write a sector in flash memory.

I am using the Flex SPI NOR API described in the reference manual.

My issue is when I try to write something at address 0x7003F000, nothing happens regarding the "Memory" view of debugger (or a variable retrieving the value), but when I reboot the board I then see the memory has been updated as I wanted it to be. Why is it updated only after a reset ?

When I write to 0x7004000, no problem everything goes fine. I thought about an alignment issue but the reference manual clearly says the address must be a multiple of 0x1000 and that is the case for 0x7003F000.

Did someone encountered the same issue ?

Do you know how to solve this ?

Thanks a lot!

Paul

0 项奖励
回复
1 解答
4,451 次查看
mjbcswitzerland
Specialist V

Hi Paul

I haven't had such behavior but one thing to remember is that when you write data to flash it takes time for the write to complete and if you write such data and immediately jump (reset) etc. the write may not be complete and, depending on what happens next, could get aborted or suspended. To avoid such problems I tend to use a (blocking) read from the chip that first waits for the busy state to be completed so that subsequent operations are ensured.

How much shared data do you have? In the uTasker project boot loader and applications share data/communicate during preserved RAM regions rather than using SPI flash.

Note also that you don't need to do page writes, you can write also just one byte without any difficulties. The page is the maximum aligned data that can be written with a single command. Sector erasure is only needed when an already written address is to be changed.

Regards

Mark

[uTasker project developer for Kinetis and i.MX RT]

在原帖中查看解决方案

5 回复数
4,451 次查看
mjbcswitzerland
Specialist V

Hi


Presumably the flash is in the cached region and its old contents still in cache after you have programmed - you will either need to take the area of interest out of the caching area or else do a cache flush after programming so that the next time you read it will return the real content again and not just take the old value from the cache. Typically the second method is used so that the content sill benefits from cache operations when it remains stable.

Regards

Mark

[uTasker project developer for Kinetis and i.MX RT]

0 项奖励
回复
4,451 次查看
paul_guirbal
Contributor II

Hi Mark,

Thanks for your reply.

I followed your advice and added SCB_CleanDCache(); right after the programming operation to flush the cache but it does not seem to change anything unfortunately.

To give you some clarifications, my code is divided in two parts: a bootloader and an application.

I also reserved a sector in flash (in the linker script) for sharing data between bootloader and application.

There is no problem when I write data to flash from the bootloader or the application separately.

The issue comes when I try to write something into the "shared data" sector (at 0x7003F000) from the bootloader whereas the application already wrote something at that space before jumping to the bootloader (via a software reset).

I also get the same issue in the other way: when I try to write something from the application at an address that was written by the bootloader before jumping to application.

But the thing is I can write once, without any problem.

Before writing I ensure to erase the entire 4KB sector and write by pages of 256B, but I found out this is the erase operation that does not seem to erase properly in the cases I described before.

Have you already met some behavior like this one?

Thanks a lot!

Paul

0 项奖励
回复
4,452 次查看
mjbcswitzerland
Specialist V

Hi Paul

I haven't had such behavior but one thing to remember is that when you write data to flash it takes time for the write to complete and if you write such data and immediately jump (reset) etc. the write may not be complete and, depending on what happens next, could get aborted or suspended. To avoid such problems I tend to use a (blocking) read from the chip that first waits for the busy state to be completed so that subsequent operations are ensured.

How much shared data do you have? In the uTasker project boot loader and applications share data/communicate during preserved RAM regions rather than using SPI flash.

Note also that you don't need to do page writes, you can write also just one byte without any difficulties. The page is the maximum aligned data that can be written with a single command. Sector erasure is only needed when an already written address is to be changed.

Regards

Mark

[uTasker project developer for Kinetis and i.MX RT]

4,451 次查看
paul_guirbal
Contributor II

Hi Mark,

Thank a lot for this answer that helped me to figure it out!

I finally went for the RAM solution that is clearly the easiest and adapted way of sharing data in such a situation.

I reserved a section in RAM via the linker script dedicated to my shared data and I access it via a simple pointer in the code.

The only thing is RAM content is cleared after a hard reset but this not critical for this project.

Soft reset does not alter the RAM content and that is exactly what I need.

Thanks again Mark!

Paul

0 项奖励
回复
4,450 次查看
mjbcswitzerland
Specialist V

Hi Paul

I locate persistent RAM data at the top of RAM and set the initial stack pointer below it - this way there are no linker scripts (and portability issues between iDEs). In most of the i.MX RT parts this means at the top of OCRAM (with the i.MX RT 1011 being an exception where it is at the top of ITC). This specific location is also guaranteed to never be used by the ROM loader when it starts the board.


The boot loader configures FlexRAM to optimise application's memory usage (allowing full speed code from ITC and full speed data from DTC) on-the-fly whereby a method has been developed to ensure that the persistent data is always at the same location (just above the initial stack pointer) no matter how the Flex RAM is configured/remapped (allowing compatibility across all chips and all memory sizes): it is illustrated in chapter "RAM and Cache" of the document https://www.utasker.com/docs/iMX/i.MX_RT_1021_uTasker.pdf

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]

0 项奖励
回复