MQX FlashX driver – how to write FlexNVM?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MQX FlashX driver – how to write FlexNVM?

MQX FlashX driver – how to write FlexNVM?

1. Few basic questions and answers about FlexNVM and FlashX.

1.1 What is FlexNVM?

FlexNVM is additional separate block of flash memory which could be used as data flash, as non volatile storage for emulated EEPROM or as combination both option. I will focus on first option in this document – FlexNVM will work simply as data flash.

FlexNVM you can find in MCU parts which contain “X” at dedicated place in part number. For example:

MK64FX512VMD12 contains 1 block (512 KB) of program flash and 1 block (128 KB) of FlexNVM

MK64FN1M0VMD12 contains 2 blocks (512 KB each) of program flash only.

For more details about FlexNVM and flash blocks, please see your MCU reference manual. For example chapter “Flash Memory Sizes”.

1.2 What is FlashX?

MQX FlashX driver provide ability to write to and read from internal flash. Unfortunately FlexNVM memory is supported only partially in default state – Some of BSPs has implemented configuration and functions for emulated EEPROM (flexnvm example code). For more details, please check MQX_IO_User_Guide.pdf in c:\Freescale\Freescale_MQX_4_2\doc\mqx folder.

1.3 Can I use BSP for MCU without FlexNVM for my own board which has MCU with FlexNVM?

It is not recommended. However you can use this BSP as base for your own board BSP. Please check MQX_BSP_Cloning_Wizard_Getting_Started.pdf, MQX_BSP_Porting_Guide.pdf  and MQX_BSP_Porting_Example_User_Guide.pdf documents in C:\Freescale\Freescale_MQX_4_2\doc folder.

1.4 Can I use FlashX in my KSDK project?

Unfortunately FlashX driver was not implemented into KSDK. KSDK contains its own Standard Software Driver (SSD) for C90TFS/FTFx Flash family, however this is just low level driver without high level abstraction layer like in case of FlashX driver.

2. Procedure for update MQX FlashX driver to support FlexNVM.

2.1 Please backup these files: user_config.h, <your BSP>.h, init_flashx.c, flash_ftfl.c and flash_ftfe.c files. Note: user_config.h, <your BSP>.h and init_flashx.c are part of your BSP code.

2.2 Enable FlashX in user_config.h file by definition:

#define BSPCFG_ENABLE_FLASHX                      1

2.3 Updates of <your BSP>.h file:

2.3.1 Please check MCU reference manual and update BSP_INTERNAL_FLASH_BASE, BSP_INTERNAL_FLASH_SIZE, BSP_INTERNAL_FLASH_SECTOR_SIZE if necessary. Typically we have to decrease BSP_INTERNAL_FLASH_SIZE in case when BSP without FlexNVM was used as base for own BSP.

2.3.2 Add new macros which will define FlexNVM in memory map. For example:

#define BSP_INTERNAL_FLEXNVM_BASE  0x10000000

#define BSP_FLEXNVM_SECTOR_SIZE         0x400

#define BSP_INTERNAL_FLEXNVM_SIZE  0x00008000

2.4 Update init_flashx.c in your BSP folder:

2.4.1 Add FlexNVM file block into _bsp_flashx_file_blocks[] table. For example:

    // data flash file block

    { "dflash", BSP_INTERNAL_FLEXNVM_BASE, (uint32_t) (BSP_INTERNAL_FLEXNVM_BASE+ BSP_INTERNAL_FLEXNVM_SIZE - 1) },

   Parameters are {name of file block, start address, end address}.

   Note: This is pure software interface; range of addresses doesn’t need fit to physical flash block parameters. You can organize file blocks according your needs.

2.4.2 If you used non-FlexNVM BSP as base for your own BSP, you have to change HW block map for KinetisX devices. Please change _flashx_kinetisN_block_map into _flashx_kinetisX_block_map in _bsp_flashx_init structure.

2.5 Update flash_ftfl.c or flash_ftfe.c file:

2.5.1 Look at MCU reference manual whether your MCU has FTFL or FTFE flash memory module and select appropriate file for editing.

2.5.2 Add FlexNVM memory block into _flashx_kinetisX_block_map[] table. For example:

{ BSP_INTERNAL_FLEXNVM_SIZE / BSP_FLEXNVM_SECTOR_SIZE, (_mem_size) BSP_INTERNAL_FLEXNVM_BASE,  BSP_FLEXNVM_SECTOR_SIZE }, // FlexNVM block

Parameters are {number of sectors, start address, sector size}.

Note: This is description of physical hardware memory block; range of addresses must fit to physical flash block parameters.

2.5.3 Now we have to fix problem with FlexNVM address. Both Program Flash and FlexNVM Flash are programmed trough FTFL_FCCOBn / FTFE_FCCOBn registers where FCCOB1.. FCCOB3 contains address in 24bit format. Therefore we cannot work directly with FlexNVM addresses – they will not fit into 24bit due to FlexNVM base 0x10000000.

FTFL/FTFE modules specifies that most significant bit in 24bit address (bit 23) will be used for distinguish between Program Flash and FlexNVM Flash. We can use for example such code:

//Set 23th bit when FlexNVM flash address

    if (write_addr & BSP_INTERNAL_FLEXNVM_BASE)

    {

write_addr = write_addr | (1 << 23);

    }

 

and add this code into necessary functions prior write into command_array[] (content of command_array[] will be used for filling FTFL_FCCOBn / FTFE_FCCOBn registers).

For basic work of FlashX example code is necessary update at least ftfl_flash_erase_sector()/ftfe_flash_erase_sector() and ftfl_flash_write_sector()/ftfe_flash_write_sector() functions.

2.6. After these changes, you can try using FlashX example code in flash_demo.c where you simply open FlexNVM file block instead of default program flash file block. For example:

//#define FLASH_NAME "flashx:bank0"

#define FLASH_NAME "flashx:dflash"

In attachment file you can find example of modification for MQX4.2.0 and MK20DX72 MCU.

3. How to rewrite flash - general notes:

Flash data must be in the erased state before being programmed. Cumulative programming of bits (adding more zeros) is not allowed.

In case of both FTFL and FTFE modules we program flash by aligned phrases (typically 64 bits). If we want program by smaller chunks (e.g by bytes), FTFL module will allow you write into this phrase even if it is not recommended. However FTFE module will cause bus fault in case of second write into the same phrase. So, only save way how to change data in FTFE phrase which was already written is erase whole sector and rewrite data back. Therefore please use ioctl command FLASH_IOCTL_ENABLE_SECTOR_CACHE for FTFE module. The sector cache allocation is not required in case of Full sector write and partial sector overwrite when the destination area (aligned to phrases) is blank.

Attachments
Comments

Hi RadekS,

We have used MK50DX256CLL10 in our system for a coil winding application. We need to get the FlexNVM/EEE feature working to store some data in the FlexNVM region upon a power failure. We tried your Flash driver code (our BSP was adopted from bspk53twr n512 that came with tower) and added memory mappings in bsp_*.h files. We are unable to get fopen("flashx:dflash") working. It returns NULL. The FlexRAM is mapped correctly and read/writes to FlexRAM work. But when system is power cycled, the data is lost as it's not written to FlexNVM.

Using the barebones code, we are able to store data in FlexNVM (it is retained after a power cycle). But when we use MQX, we see the above problem. I have a feeling that some setting in BSP is not right and hence we are not able to open D: flash (flexNVM for our processor starts at 0x10000000). Perhaps it's not getting mapped correctly. We followed all the steps in your examples but it still fails

(e.g

4 Update init_flashx.c in your BSP folder:

4.1 Add FlexNVM file block into _bsp_flashx_file_blocks[] table. For example:

    // data flash file block

    { "dflash", BSP_INTERNAL_FLEXNVM_BASE, (uint32_t) (BSP_INTERNAL_FLEXNVM_BASE+ BSP_INTERNAL_FLEXNVM_SIZE - 1) },

   Parameters are {name of file block, start address, end address}.

   Note: This is pure software interface; range of addresses doesn’t need fit to physical flash block parameters. You can organize file blocks according your needs

4.2 If you used non-FlexNVM BSP as base for your own BSP, you have to change HW block map for KinetisX devices. Please change _flashx_kinetisN_block_map into _flashx_kinetisX_block_map in _bsp_flashx_init structure.

...

We followed all the above steps but fopen() still fails. Please suggest if we are missing anything else in configuration.

thanks,

-shridhar

shridharmv@gmail.com

Hi Shridhar,

For FlexNVM:

You have to edit also _flashx_kinetisX_block_map[] table in flash_ftfl.c file and add there description of FlexNVM block.

For FlexRAM:

Did you use flush/close functions prior power down?

Example how to use FlexRAM could be found here c:\Freescale\Freescale_MQX_4_2\mqx\examples\flexnvm

Until we enable EEPROM emulation, target FlexRAM memory range works like “standard” RAM.

Of course, you have to choose whether you will use FlexNVM memory as data flash, as emulated EEPROM or you could divide FlexNVM memory into two sections and use both option (in that case, memory ranges must be updated accordingly).

Anyway, FlexNVM memory with default setting at empty MCU could be used as data flash and FlexRAM as “standard” RAM. If you would like use emulated EEPROM (FlexRAM), you have to configure FlexNVM memory for that (Program Partition command and Set FlexRAM Function command). See flexnvm example code...

Hi Radek,

We have done all steps that were mentioned in your original post - so we have also edited _flashx_kinetisX_block_map[].  And I just checked our code, we are doing a fclose() at the end of writing to FlexRAM (with EEE feature).

If we do not enable EEE (no emulated EEPROM) and just want to use FlexNVM as extended flash (say as D: flash), the steps you mentioned should have worked for us. I mean, we must have been able to fopen("") the D: flash. But that is failing too. So if we first get past this problem, I believe we will be able to get our reads/writes working with EEE enabled.

Note that, partitioning of FlexNVM is working correctly.  In the absence of partitioning, FlexNVM will remain inaccessible. But once it is partitioned (say 128 KB as D flash and remaining for EEE or E: flash), we should be able to use the fopen() and other file operations on that portion, right? But that doesn't work.

So I am thinking for EEE to work, we must first make FlexNVM accessible to us ... Which seems to be accessible from barebones code but strangely once MQX is running, is not ...

This is really a critical requirement for us - power fail feature needs this functionality.

thanks,

-shridhar

Thank you for clarification.

If you have “empty” MCU, you should be able access whole FlexNVM as extended flash (say as D: flash).

Once you already execute Program Partition command, you could use only dedicated part of FlexNVM as extended flash. Program Partition command parameter told you how big part of FlexNVM remained for extended flash (you could use FLEXNVM_IOCTL_GET_PARTITION_CODE command for read current partitioning settings). Part of FlexNVM dedicated for emulated EEE is not accessible by standard flash commands. Only Erase All Blocks command could reverting partition settings (erase flash IFR space).

So, if you already partitioned FlexNVM let’s say to 128kB for Data flash and 128kB for EEE (DEPART=5), you have to modify BSP_INTERNAL_FLEXNVM_SIZE accordingly. In our case it should be 0x20000.

Best Regards

RadekS

Note:

You wrote that you use MK50DX256CLL10 and you use own BSP was adopted from bspk53twr n512.

I suppose that you mean twrk53n512 BSP in MQX. Correct?

Could you please look at mask on your MCU package?

The twrk53n512 BSP was designed for old 100MHz Kinetis version with mask N30D (part number with Z in name) and newly delivered TWR-K53N512 boards are assembled with new 100MHz version with mask 4N22D or 5N22D. So, newly delivered TWR-K53N512 boards are not fully compatible with twrk53n512 BSP in MQX.

http://www.freescale.com/files/microcontrollers/doc/eng_bulletin/EB782.pdf

http://www.freescale.com/files/32bit/doc/app_note/AN4445.pdf

If you are using Kinetis Rev2.x (mask N22D), rather twrk60d100m or twrk40d100m BSPs should be used template for your own BSP.

Best Regards

RadekS

Hi RadekS!

Thanks for the responses. Even when we have no partition(say on a fresh boot after a mass erase and without partition), the fopen to D: flash still fails. That is our real problem I guess. I mean without emulated EEPROM, why are we not able to access FlexNVM as D:flash?


We changed the BSP_INTERNAL_FLEXNVM_SIZE  to 128 K (0x20000) as you suggested after partition (128k - 128K) and it still fails (fopen to D: flash which is made available as extension to P: flash).

We didn't adapt the Freescale boards for our product but build our own based on our needs (I mean the PCB on which the MCU is mounted was designed in house in our office). But we took the BSP from twrk53n512 in MQX like you have noted.

We found that writes to external Flash are working during a power fail. So we can still get our power fail feature working but I would hate to give up FlexNVM/EEE feature as it gives us faster write times and enhanced endurance.

Appreciate all your help and still hoping to find an answer to why our fopen to D: flash should fail :smileyhappy:

thanks,

-shridhar

Hello Radek,

Thanks for the explanation.  I had all but given up on getting FlexNVM Data Flash working till I found your post.

I'm using:

MQX: 4.2 with 4.2.0.1 patch installed

BSP: For TWR-K70F120M (Uses MK70FN1M0VMJ12 MCU, which contains 1 MB Program Flash and does not have FlexNVM)

Toolchain:  CodeWarrior v10.6  Build Id:140329

Our custom High-Speed Data Logger board uses the MK70FX512VMJ15 MCU, which contains 512 KB Program Flash and 512 KB FlexNVM.

Using your instructions, I have Data Flash working on our custom board.  I first cloned bsp_twrk70f120m to create bsp_HS_Logger for our custom board and then I applied your instructions to get Data Flash working.  I'm able to run the FlashX example code in flash_demo.c as you suggested.  However, I'm not completely sure I have everything set up correctly.

Here are my variations on your instruction, which seemed to apply for the MK70FX512VMJ15 MCU we're using:

Step 2.3:  Updated our .h file (which for us is HS_Logger.h) as follows:

Changed: 

#define BSP_INTERNAL_FLASH_SIZE     0x00100000

To:

#define BSP_INTERNAL_FLASH_SIZE     0x00080000

Added:

#define BSP_INTERNAL_FLEXNVM_BASE     0x00100000

#define BSP_INTERNAL_FLEXNVM_SIZE     0x00080000

#define BSP_FLEXNVM_SECTOR_SIZE          0x1000

Step 2.5:  Updated _flashx_kinetisX_block_map[] table in flash_ftfe.c by adding one entry as follows:

{ BSP_INTERNAL_FLEXNVM_SIZE / BSP_FLEXNVM_SECTOR_SIZE,  (_mem_size) BSP_INTERNAL_FLEXNVM_BASE,  BSP_FLEXNVM_SECTOR_SIZE },

Question:  Since the MCU Reference Manual says the MK70FX512VMJ15 has 2 blocks of Data Flash, should I have made two 256 KB Data Flash entries into the _flashx_kinetisX_block_map[] table in Step 2.5, instead of just one 512 KB Data Flash entry?

Thanks,

Damon

Hi Damon,

Definition “#define BSP_INTERNAL_FLASH_SIZE    0x00080000” looks OK.

The BSP_INTERNAL_FLEXNVM_BASE should be 0x10000000 according K70 RM. Since Flash module works only with 24bit addresses you could define BSP_INTERNAL_FLEXNVM_BASE directly as 0x00800000 and in that case you could skip modifications according chapter 2.5.3. This should work, however it might be very confusing since this value do not fit with values in RM.

Since you access both Data Flash block by the same flash module and they are concatenated into one memory block without gaps, you don’t need to take define two blocks in _flashx_kinetisX_block_map[] table.

The information about physical blocks (logical program flash blocks) is important mainly from allowed simultaneous flash operations point of view. “The user may read from one logical program flash memory space while commands are active in the other logical program flash memory space.”


I hope it helps you.

Have a great day,
RadekS

Hello Radek,

Thanks for getting back to me so quickly.  You've proved to be very knowledgeable and helpful on this subject.

Regarding BSP_INTERNAL_FLEXNVM_BASE, I had a typing error in my post.

The actual definition in my cloned BSP .h file (HS_Logger.h) is as follows:

     #define BSP_INTERNAL_FLEXNVM_BASE     0x10000000

I had also made your 2.5.3 changes, which is why Data Flash writing / reading is working for me.  But I see from your answer, that I could skip the 2.5.3 modifications, if I change my BSP_INTERNAL_FLEXNVM_BASE definition from 0x10000000 to 0x00800000.  I assume this is because bits 24 through 31 of Data Flash addresses are essentially "don't care" bits, since the FTFE_FCCOBn registers contain only 24-bit addresses, with Data Flash addresses indicated by a "1" in bit 23.  I agree this might be confusing for someone reading / maintaining the code in the future, so if I implement this way, I would add some carefully worded comments (along the lines of the text in my Question #1, below).

Question #1:

Am I right in concluding:   Since FTFE FlashX, for the MK70FX512VMJ15 MCU, uses only 24-bit addresses, the 512 KB Program Flash and 512 Data Flash could be thought of as being located in the following "virtual" address ranges?

     512 KB Program Flash:     0x00000000-0x0007FFFF   (two 256 KB blocks for simultaneous operation purposes)

     512 KB Data Flash:            0x00800000-0x0087FFFF   (two 256 KB blocks for simultaneous operation purposes)

Question #2:

Regarding the 512 KB FlexNVM memory (0x10000000-0x1007FFFF), the MK70FX512VMJ15 MCU Reference Manual says it can be used as Program Flash, Data Flash or a combination of both, if I am interpreting it correctly.  I would like to have the option for my application program to grow larger than 512 KB, which would then require more than 512 KB of Program Flash for code execution.  So far, I have not been able to figure out the required coding and/or MQX source/make/link file changes that would allow me to use some of the FlexNVM at 0x10000000 as Program Flash.

For example, could I have three 256 KB Program Flash Blocks (0x00000000-0x0003FFFF, 0x00040000-0x0007FFFF and 0x10000000-0x1003FFFF) and also have one 256 KB Data Flash Block (0x10040000-0x1007FFFF)?

What changes would I have to make to accomplish this?

Thanks,

Damon

Hi Damon,

Thank you for clarification.

Q1)

Yes, it looks OK. I didn’t test it, but it should work for FlashX driver.

Of course, your code should not use addresses higher than 0x10000000 any more with that configuration. Instead of that you should use (relative address + BSP_INTERNAL_FLEXNVM_BASE) as parameter.

Q2)

FlexNVM could work as standard Flash until you partition it as emulated EEPROM.

So, If you would like use FlexNVM as Program Flash, you should just update your linker file (file extension depends on your tool chain (for example *.ld, *.icf,…)) and extend ROM range.

You could use FlashX driver to write into both P-flash and D-flash. Of course it is wise to keep P-flash and D-flash separated (typically we do not want rewrite our code by data). This could be simply managed by linker file (limits P-flash range) and by FlashX driver settings in _bsp_flashx_file_blocks[] table (limits D-flash range).


I hope it helps you.

Have a great day,
RadekS

No ratings
Version history
Last update:
‎06-02-2015 08:35 AM
Updated by: