writing to flash in XIP mode

bxwen

Member
This is not a problem directly about Teensy. I searched and asked in NXP forum without getting a clear answer.

When in XIP mode, can processor like rt1064 write to the same flash chip itself? Some people say yes, as far as you can locate that part of the code in memory and stop all the interrupts. Some say no, only if there are more than one flash chips or a dual port flash.

May I ask how this problem is handled on Teensy 4.1? According to memory map in https://www.pjrc.com/store/teensy41.html, the code is running from the same flash chip that has a LittleFS system.

Thanks.
 
Yes, it obviously must be possible because LittleFS does it on Teensy.

The details of how can be found in the LittleFS library source code.
 
Yes, it obviously must be possible because LittleFS does it on Teensy.

The details of how can be found in the LittleFS library source code.

Was wondering if it is due to 32KB code cache? XIP or any Flash code (especially on locked/encrypted) 1062 would need to be made available/plain to run. If that code then blocks flash access during writes (also EEPROM access) it would do so from the cache?
 
Trying to write to the flash, I had all kinds of instability issue. I finally have to relocate almost all the code to memory. The complication in my case is the use of FreeRTOS. It doesn't seem to recover properly after interrupt is disabled and enabled.
 
Indeed, RTOS is its own set of issues/details.

Is this RTOS running on a Teensy with an NXP 1062?

If so, do EEPROM writes work?
 
no, this is another board we built for our camera application. The same NXP 1062 is used. I would have used Teensy if UVC is implemented on Teensy.
 
Hello Paul,

I've been searching for the topic "writing to flash in XIP mode" and found your post above saying
> Yes, it obviously must be possible because LittleFS does it on Teensy.
> The details of how can be found in the LittleFS library source code.
You should know it as you appear to be the author of the software.

In the schematics I find the serial 8 MByte flash W25Q64JV being connected to SD_B1_06 ... SD_B1_11.
In the memory map I find the a 8 MByte flash being used for code, LittelFS filesystem and EEPROM emulation.
Although XIP is not mentioned, I assume the W25Q64JV is being mapped into the address range of the microcontroller via XIP.
The micro controller is executing code from the serial flash and there must be also erase/write operations ongoing in the same serial flash for the LittleFS filesystem and the EEPROM emulation.

`int LittleFS_QSPIFlash::erase(lfs_block_t block)` appears to implement the block erase function.
It utilizes the function `flexspi2_ip_command()`
`int LittleFS_QSPIFlash::wait(uint32_t microseconds)` appears to implement the wait for the busy flag, guarded by a timeout.
It utilizes the function `flexspi2_ip_read()`

How does it work?
Is the code fetched via the AHB bus mapped to the address space via XIP while the commands for erase and write are sent via the IP command bus without leaving the XIP mode?
Basically as described here: https://community.nxp.com/t5/Layerscape-Knowledge-Base/FlexSPI-Driver-Design/ta-p/1354159
and in the attached "FlexSPI Driver Design.pdf" in the figure on page 2 in chapter 1.2 FlexSPI Command Interface?

Are the instructions generated from LittleFS.cpp actually located in one of the code sections inside the serial flash while in parallel writing to the same flash with the LittleFS file system?
If so: Respect, cool work.
If not: Could you explain how it actualy works?
 
Are the instructions generated from LittleFS.cpp actually located in one of the code sections inside the serial flash while in parallel writing to the same flash with the LittleFS file system?
If so: Respect, cool work.
If not: Could you explain how it actualy works?
In short: no. The code is stored in the flash but at startup gets copied into the ITCM memory and runs from there. It's still possible to execute code directly from flash (functions tagged with the FLASHMEM attribute don't get copied to ITCM and use XIP) but that is not the case for the eeprom functions that perform the actual programming.
 
Check out the "Memory" section of the Teensy 4.1 page for detailed documentation.

teensy41_memory.png


Might also be worth mention, if you're used to the way NXP's SDK does things... well, we're a bit more creative with how things on done on Teensy. ;)
 
Many thanks to all of your replies. Now I think I got the full picture.
1) code to erase/program serial flash is stored in flash FASTRUN Code, but not executed from there
2) code to erase/program serial flash is copied at startup to FASTRUN Code in ITCM in RAM1 and executed from there
3) general flow of erase/program functions:
- disable interrupts (in order to not accidentially access the serial flash while it cannot respond because it is busy with erase/program operations)
- send a series of commands via the IP command interface, i.e. for `eepromemu_flash_write()`
-- send command 06h (write enable)
-- poll interrupt flag until done
-- clear interrupt flag
-- send command 32h (quad write)
-- poll interrupt flag until done and if there is more data to be transmitted and data can be sent to the IP command interface `(n & FLEXSPI_INTR_IPTXWE)`, copy it in chunks of 8 bytes to FLEXSPI_TFDR0
-- clear interrupt flags
- continue with `flash_wait()`
--- send command 05h (read status)
--- poll interrupt flag until done
--- clear interrupt flag
-- check the busy flag of the response of the serial flash, if still set repeat the above three actions
-- purge stale data from FlexSPI's AHB FIFO and wait until done
-- enable interrupts (from this point on XIP will work again as the serial flash is responsive again)

To my understanding, the underlying principle can be used with any microcontroller architecture that supports XIP and SPI communication with a serial flash, it is not restricted to NXP and FLEXSPI. Of course, the method how to send commands and data to the serial flash have to be adapted.
Basic principle:
- execute flash erase/program routinse form a memory that remains accessible while the flash is busy
- disable interrupts
- send required command sequence
- poll flash status until no longer busy
- enable interrupts

The big drawback with this scheme is that the realtime behaviour of the system is basically stalled while flash erase/program is ongoing.
 
Back
Top