Flash Swap Feature for k22fn1M0

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

Flash Swap Feature for k22fn1M0

1,984 Views
anujtanksali
Contributor II

Hello, 

I wanted to use the flash swap feature in my device K22FN1M0. Please let me know if any example KDS project is available for the same. I am not able to find any good example project which shows the flash swap feature.

Thanks,

Regards,

Anuj

Labels (1)
Tags (1)
0 Kudos
25 Replies

1,413 Views
mjbcswitzerland
Specialist V

Hi

See https://community.nxp.com/thread/379755?commentID=587268#comment-587268 

Real-world loaders using the swap feature, swap block driver and simulation of the process (in Visual Studio) are available in the open source uTasker project (see below).

Regards

Mark

Complete Kinetis solutions for professional needs, training and support: http://www.utasker.com/kinetis.html
Kinetis K22:
- http://www.utasker.com/kinetis/FRDM-K22F.html
- http://www.utasker.com/kinetis/TWR-K22F120M.html
- http://www.utasker.com/kinetis/BLAZE_K22.html
- http://www.utasker.com/kinetis/tinyK22.html

uTasker: supporting >1'000 registered Kinetis users get products faster and cheaper to market
Request Free emergency remote desk-top consulting at http://www.utasker.com/services.html

Open Source version at https://github.com/uTasker/uTasker-Kinetis

0 Kudos

1,413 Views
anujtanksali
Contributor II

Hello Mark,

Thanks for your inputs. I was able to configure k64 in config.h as k22 dosen't seem to have MEMORY_SWAP define. 

I am compiling the uTasker serialloader_FLASH. 

Am getting error in file usb_device_loader.c:1229: undefined reference to `fnHandleSwap'

Regards,

Anuj

0 Kudos

1,413 Views
mjbcswitzerland
Specialist V

Hi Anuj

Please enable the serial interface in config.h:

#define SERIAL_INTERFACE                                             // enable serial interface driver

Since the swap operation is controlled by a menu on the serial interface (or USB-CDC) the swap routine is not linked when this is not enabled.

To use with K22 you can select FRDM_K22F and then change the SRAM and Flash sizes in app_hw_kinetis.h (for the FRDM_K22F) to match your chip.

Add

#define MEMORY_SWAP                                                  // use memory swap method

to the FRDM_K22F configuration (this is not there by default because the chip on the board can't do it) so that the method is selected.

Also add
#define SUPPORT_SWAP_BLOCK                                           // support flash swap block

to the FRDM_K22F configuration (in app_hw_kinetis.h) so that the swap block driver in kinetis_FLASH.h is activated.

All of the low level code is found in

extern int fnSwapMemory(int iCheck);

in that file.

If you build with Visual Studio you can put a break point in fnFlashNow() where the flash simulator can also be seen that emulates the flash behavior based on the commands that it parses.

Regards

Mark

0 Kudos

1,413 Views
anujtanksali
Contributor II

Hello Mark,

Thank you very much. I was able to compile the code without any errors by doing the above suggestions.

I was able to port the code from the uTasker project to my project which uses K22FN1M0 device.

I had to replace FTFL used in uTasker project with FTFE memory configuration as my device references are using FTFE. I verified the addresses for FTFL and FTFE used in my project and they are same.

my flash size if 0x100000 which is 1MB

swap indicator address is 0 + (0x100000/2) - 0x1000 ( 4KB sector size)

so last sector of the first swap block is used for swap indicator address.

1) Initially for just testing purposes at bootup i run the function fnHandleSwap(1).

2) After this is called then fnSwapMemory(1) is called

3) Then fnFlashNow is called which returns (FTFE_FSTAT & (FTFE_STAT_ACCERR | FTFE_STAT_FPVIOL | FTFE_STAT_MGSTAT0)); // if there was an error this will be non-zero

the FTFE_FSTAT is 0xa0 which indicates ACCERR error as per datasheet.

Can you please let me know the cause for this ACCERR errror? 

Attached is my flash swap code.

Also I had one query regarding swap. 

As per the link which you have sharedhttps://community.nxp.com/thread/379755?commentID=587268#comment-587268 

swap by default works on half area of flash. i.e. if 1MB flash is present then lower 512K and upper 512K will be swapped. In our application we are using a bootloader which will be at address 0 in flash. Application will start at address 0x4000 for ex. in this case how will the flash swap work?

Can we specify flash swap starting address as 0x4000 so that only the application area is swapped?

If not then i think bootloader should be included in the image which is going to be downloaded OTA and then swap is initiated. 

Can you please confirm whether flash swap always acts on 2 half areas of flash and there is no way to change the start address from which swap will work.

Regards,

Anuj

0 Kudos

1,413 Views
mjbcswitzerland
Specialist V

Hi Anuj

The swap feature works always on half the flash size. Any bootloader used must therefore also be loaded to the second swap block and then starts after the swap has taken place.

Note that the uTasker flash driver works for both FTFL and FTFE flash controllers: it adapts itself accordingly.

An access error will be due to something (like an address) not being set correctly (or set illegally) and the flash controller couldn't complete the operation.

Regards

Mark

0 Kudos

1,413 Views
anujtanksali
Contributor II

Hello Mark,

Thank you for your reply.

I was able to find the issue with access error. The uTasker project FTFL_BLOCK is not a pointer. it is a value.

I was using FTFE_BASE_PTR + 0x08 instead of FTFL_FCCOB7_4 in uTasker project which expands to *(unsigned long*)(FTFL_BLOCK+0x08). In UTasker FTFL_BLOCK is only a value not a pointer. In my project FTFE_BASE_PTR is a pointer.

I used a different define for FTFE_BASE value as 0x40020000u and used it. The swap commands execute ok now. 

Thanks,

Regards,

Anuj

0 Kudos

1,413 Views
mjbcswitzerland
Specialist V

Hi Anuj

In the uTasker project FTFL_BLOCK is in fact an 'uncasted' pointer. This means that
#define FTFL_FCCOB7_4       *(unsigned long *)(FTFL_BLOCK + 0x08)
gives the "casted" pointer to and unsigned long at 0x40020008.

If you were using a 'casted' pointer for FTFL_BLOCK it could give a different value, depending on what the casting was.

However I have understood that you could now successfully use the uTasker code to solve your project.

Regards

Mark

0 Kudos

1,413 Views
anujtanksali
Contributor II

Hello Mark,

Yes I got your point.

I had another query related to Flash Swap. If flash is secure then i cannot perform a swap right?. 

So in case when i am doing a soft reset of the system after first swap if the flash will be secure so will i have to unsecure it first before performing a second swap? Is my understanding correct? or the swap code automatically takes care of this.

if yes then how do i unsucure the flash in code?. Is this done in uTasker project. If yes then please let me know where in uTasker project.

Thanks,

Regards

Anuj

0 Kudos

1,413 Views
mjbcswitzerland
Specialist V

Anuj

I am not aware of any flash swap restrictions when the processor is secured; the full command set is available in NVM Normal mode. Only in NVM special (eg. when commanded via JTAG) are command restricted.

The only way to un-secure the processor from code is to make a backup of the first Flash  sector content (to SRAM) and change the security setting there. Then delete the first sector and reprogram it with the backup (and changed security setting), and command a reset.

The above is always risky since if there were a power failure (or other reset) during the process the processor will not start again without being re-programmed.

Regards

Mark

0 Kudos

1,413 Views
anujtanksali
Contributor II

Hello Mark,

Thanks for the reply. I have a application note AN4533 document which describes the Flash Swap on Kinetis Microcontrollers. In section 5.4 Important considerations

point 1 "Always program the vector table and flash configuration fields"

it is specifically given that 

"***

You must program the interrupt vector table and flash configuration fields (FSEC, FOPT, and so on) to the nonactive upper
block before swapping. If not, the vector table and flash configuration will not be set correctly in the new active block after
the swap. This will result in unwanted configurations and could potentially secure the device.

***

please see attached document "AN4533_Flash Swap for Kinetis Microcontrollers.pdf"

When i perform swap for the first time i.e. call flash_HandleSwap(0) and then when i again try to debug the K22FN1M0 device using PE Micro debugger i get a message "Flash is secure. Erase to Unsecure?"  Yes , No

When i do not perform any swap and again debug the K22FN1M0 device i do not get any message related to flash erase.

so it seems due to swap operation performed earlier the flash is getting secured. 

Can you please let me know if a swap call flash_HandleSwap(0) will secures the flash? and How do i avoid this?

Or this will not cause an issue when the application is actually running and i can call  flash_HandleSwap(0) to perform a swap each time without any issue.

Regards,

Anuj 

0 Kudos

1,413 Views
anujtanksali
Contributor II

Hello Mark,

I may have found the issue with flash secure. As per the document it is given that non active upper block must be programmed first with valid vector table and flash configuration. If not then it may result in flash secure. In my case the upper block was empty not programmed with anything.

So it means i will have to perform swap only after i have verified my OTA image is valid and authentication of the image is done. Is my understanding correct?.

So i will call the flash_HandleSwap(0) function only when OTA image is authenticated. 

But do to some reason the upper block gets corrupted during system reset and swap is already performed before reset then the flash will be secure and system may not boot due to corruption and i will not be able to recover it easily. 

How do i avoid this?

Thanks

Regards,

Anuj

0 Kudos

1,413 Views
mjbcswitzerland
Specialist V

Anuj

After you have performed the swap the processor will boot from the alternative half of memory (that is, the other half of memory now appears at address 0). This means that the processor boots from there and also takes its flash configuration settings from there.

It is important that the flash configuration is set accordingly because a non-programmed configuration will indeed secure the device (but can be unsecured) with the debugger. In some cases device securing is desired, but there are also other settings (like NMI disable) that need also be considered.

It is also imperative that after you have programmed the application to be switched to that you check its integrity before doing the actual switch. If you switch to a partially, or incorrectly, loaded second application it will then fail. If it fails there is no way to recover without using a debugger again. The swap method is only reliable if you are 100% sure the new code loaded is the correct one and that you know that it was programmed without errors. If there are doubts of being able to ensure this (eg. using authentication before swapping) a standalone loader that can always recover is more suitable. [The uTasker project also includes various stand-alone loaders that can be used on the K22FN1M and tend to be more popular than swap block mode - the method then also works on any chip without needing the swap feature in the HW and in fact is no less efficient than the swap method, which is really interesting only when a backup of the original code should be retained and possibly switched back to later].

Regards

Mark

0 Kudos

1,413 Views
anujtanksali
Contributor II

Hello Mark,

Thanks for the information. 

The document (AN4533_Flash Swap for Kinetis Microcontrollers.pdf) which i shared in the earlier message describes particular steps to b carried out for first swap and next swap calls.

The steps are like

1) Initialize the swap system 

2) Erase the non active upper block

3) Re program the non active upper block with new software

4) issue command to set the swap system to complete

5) reset the system for swap to take affect. 

Similar steps are for second time swap call. 

But the uTasker project swap function call handles everything at one go. 

If I call flash_HandleSwap(0) once then depending on swap system states, the changing of swap states is handled internally by the function.

So if this function is called after the OTA image is downloaded,stored in the non active upper block and authenticated and not as per the exact steps given, will this work? If yes then will it work the same for subsequent swap calls also i.e. second swap and so on. 

Regards,

Anuj

0 Kudos

1,413 Views
mjbcswitzerland
Specialist V

Anuj

fnSwapMemory(0) is realised as a state-event machine, whereby the initial state is taken from the devices itself (using the REPORT SWAP STATUS request). This means that it performs a swap from any initial state without the caller needing to know what this initial state was. It can however be used with fnSwapMemory(1) to get information about the initial state without performing a swap.

The application note that you are following mixes up a typical application's requirement with the actual swap process. Only steps 1 (optional), 3, and 5 are parts of the swap process - the steps 2 and 3 are not swap operations as such but logical application preparation if a swap to a new application were to be performed; for example, they would not be necessary if swapping between two already programmed application were required.

fnSwapMemory(0) operation also manages the flash swap indicator (which occupies the final sector of the first bank in flash, which can't be used by code); deleting and programming it as required as a part of the swap mechanism.

The uTasker swap based loader (serial or USB) allows programming and switching to any number of new applications, It also allows switching between two already programmed applications as often as required. It uses fnSwapMemory(0) to do this in each case, and so nothing else should be required with regards to the swap operation itself.

Note however that fnHandleSwap(1); should always be called once after each reset so that it can check that the reset didn't take place while a swap operation was still in progress (this operation can continue after a reset), whereby it ensures that all such operations complete and the initial state is defined before continuing.

In fact, the uTasker swap loader tends to call fnSwapMemory() from a cover function 

extern void fnHandleSwap(int iCheck);

which gives debug information about the swap state, which bank is active, any errors occurring in the processor, plus generates a delay when swapping before a reset is performed.

Regards

Mark

0 Kudos

1,413 Views
anujtanksali
Contributor II

Hello Mark,

Thanks for the reply. 

Currently am testing the swap mechanism on my hardware. I am able to program my hardware on first OTA and swap is also successful. System reboots successfully with new firmware. But I have some doubts regarding second OTA.

Suppose I have firmware version 1 and i perform a first OTA to program version 2. Suppose first OTA is successful and Swap is successful. After system reset i am able to see the new version 2 is booting successfully. 

Now I perform a 2nd OTA request with firmware version 2 running. As Firmware version 2 is physically on upper block and logically running from lower block. So can I erase the upper block in this case? if yes then should i erase the flash swap indicator sector or swap mechanism will take care of it?

Another thing is consider a use case where I am programming the firmware version 3 in upper block and before the completion of OTA for programming version 3 there is a power cycle then what will happen to firmware version 2 as physically firmware version 2 is on upper block?

If firmware version 2 is partially programmed and power cycle occurs then how will the swap mechanism handle this?. In this case the system will not contain the latest firmware version i.e. 2 it will contain only firmware version 1. 

Please let me know my understanding is correct? 

Regards,

Anuj

0 Kudos

1,413 Views
mjbcswitzerland
Specialist V

Anuj

- You can do anything you like with the upper flash block since if the swap is not commanded it can contain anything you like.

- The flash swap indicator details are handled automatically during the swap process

- If you swap to code that is invalid you will "brick your HW and it will need to be recovered with a JTAG or EzPort tool. It is up to the overall application to ensure no swap is attempted before the new image is know to be correct - the swap operation doesn't accept this responsibility. Therefore ensure that the swap sequence is never commanded unless sure - eg. that the new code was only partically programmed due to a reset/power failure, etc.

Regards

Mark

0 Kudos

1,413 Views
anujtanksali
Contributor II

Hello Mark,

Thanks for your reply. Suppose one round of swap has already taken place and swap system is in READY state and firmware version is 2. If another OTA is performed which does not complete and system reset occurs. Note that i perform a swap operation only when i received whole OTA image from server. So in this case if i erase the upper block when swap system is in READY state and system reset occurs then my firmware version 2 will be erased. I will be left with firmware version 1 only which is already physically present in active block. Is my understanding correct?

Regards,

Anuj

0 Kudos

1,413 Views
mjbcswitzerland
Specialist V

Anuj

The "upper block" is the one that is not holding the present boot code - that is, it changes on each swap.

This means that you can always erase the "upper block" without risk of not being able to boot again.

Regards

Mark

0 Kudos

1,413 Views
anujtanksali
Contributor II

Hello Mark,

Thanks for the info. The swap system is working fine on our hardware and we are able to do multiple OTA's without any issue.

Regards,

Anuj

0 Kudos

1,409 Views
anujtanksali
Contributor II

Hello Mark,

How do i revert the swap so that previous working firmware is running from active block 0.

It is observed that after swap the swap system indicates whether block 0 is being used or block 1 is being used.

we do a image validation in bootloader where application CRC is checked. If block 0 is being used and application CRC fails then we want to revert to previous application i.e. block 1 and vice versa. 

Currently if application CRC fails when block 0 or block 1 is running we erase the last sector of non active block where flash swap indicator is present and reset the system to revert to previous application. Is this the correct way to revert to previous application?. 

It is also observed that when block0 is running and flash swap indicator address sector is erased and system is reset then the swap system state changes to "uninitialized" and when block1 is running and the swap indicator address sector is erased and system is reset then the swap system state changes is block0. Is this behavior correct?. I will verify and confirm this behavior. 

Regards,

Anuj

0 Kudos