Write Data to Internal Flash While the Code is Secured

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

Write Data to Internal Flash While the Code is Secured

Jump to solution
995 Views
abdullah_cinar
Contributor III

I'm trying to write 384 bytes of calibration data to the flash on my MKV10Z32. I also have the flash secured. The write operation and flash secure operation works well. But when I try to read my calibration data on device startup, it works unexpectedly. It succeeds to read the calibration data on a startup, but when I reset the device, it can not read it at this startup. Then I reset the device again and now it can read it. It works on one startup and it does not work at the next startup and so on.

As I know, there shouldn't be any restriction to read/write to flash from firmware when the flash is secure. Please help me to solve this issue because I can not get any reason for this to happen...

I attached my flash file that contains flash protection operation, read calibration and write calibration functions. 

Tags (2)
1 Solution
854 Views
abdullah_cinar
Contributor III

I finally solved the problem. I found out that it is only allowed to write 1 sector of flash in a flash program routine. My flash addresses were corresponding to such an address that does not end up writing only 1 sector but writing some of the data to 1 sector and overflowing to the other sector. So I changed my code, I am calculating the addresses with respect to the sector sizes. I set each address to one of a sector start:


#define FLASH_SIZE_KB                           32

#define SECTOR_SIZE                              1024

#define FLASH_END_ADDR                       ( FLASH_SIZE_KB * 1024) 

#define CAL1_SIZE                                     ( sizeof(calibration1_t))

#define CAL2_SIZE                                     ( sizeof(calibration2_t))


CAL1_Addr = FLASH_END_ADDR - CAL1_SIZE;

/* Put the start address to the start of a sector (to prevent splitting the data to 2 sectors) */
if( (CAL1_Addr % SECTOR_SIZE) != 0)
   CAL1_Addr = CAL1_Addr - ( CAL1_Addr % SECTOR_SIZE );         //Result:    31744

CAL2_Addr = CAL1_Addr - CAL2_SIZE;

/* Put the start address to the start of a sector (to prevent splitting the data to 2 sectors) */
if( (CAL2_Addr % SECTOR_SIZE) != 0)
   CAL2_Addr = CAL2_Addr - ( CAL2_Addr % SECTOR_SIZE );         //Result:    30720

View solution in original post

6 Replies
854 Views
FelipeGarcia
NXP Employee
NXP Employee

Hello,

I recommend you to check chapter 30.4.12 from the Reference Manual. Related text quoted below:

The flash memory module holds off CPU access during the reset sequence. Flash reads are possible when the hold is removed. Completion of the reset sequence is marked by setting CCIF which enables

flash user commands.

I believe you are reading flash when the reset sequence has not been completed. This will result in unexpected behavior.

 

Please let me know if this helps.


Have a great day,
Felipe

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
854 Views
abdullah_cinar
Contributor III

Hello Felipe,

Thanks for the answer. I was not able to find the support tickets, so I had created this topic first. But since you are handling both of them, we can close the case and continue from here.

My flash secure function call was done after my flash read function call (read calibration data). So after reading your answer, I changed the order and put the flash secure function call at the very beginning of my initializations. I also added a dummy delay at device startup to wait for things to get ready. 

Now I realized that if I put the flash secure operation at the beginning of my initializations, I can not read the calibration data even once. Now I'm not sure if it is because I can not write my calibration data to flash after the flash secure operation or because I can not read it. How do I know what cause the problem? If I disable flash secure operation, I can read and write to flash successfully without any problem on device resets. I can also double check it by reading the flash hex (since there is not security). But I don't know how to know the cause of the problem when the device is secured.

If there is something wrong with my flash secure operation, can you please give me a routine to prevent others to read our hex firmware from outside? We don't want to limit the flash read/write operations which are requested by the firmware itself. Our hardware and firmware are ready except this flash security operation. We have completed the firmware test, then I added the flash security function and finish the development process and get to the production stage. But I realized that this function affects the test of the application.

Sorry for the long post.

Thanks.

0 Kudos
854 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi,

 

Through firmware, the user can read, erase, and program the flash in the same way, even if the device is secured. The flash is not accessible to the outside world, but from within the part, the flash can be used normally.

 

Please check chapter 30.4.11.2 of the Reference Manual.

If the flash security byte is successfully programmed, its new value takes affect after the

next chip reset.

Could you please try to read and write the flash after startup?

 

Best regards,

Felipe

0 Kudos
854 Views
abdullah_cinar
Contributor III

Hello Felipe,

Thanks for the answer. 

I already know that the protection takes effect after the chip reset. Did you review the code I attached above? I'm calling the flash secure function first and then read and write data to flash. I tested it after several chip resets but I still can not read it when the flash secure function is called. If I comment out the flash secure function call, it works successfully. Can you please help me to find the problem? Is that related to my flash protection function? Am I doing something wrong?

0 Kudos
854 Views
abdullah_cinar
Contributor III

Hello again,

I realised something. I'm writing 2 different calibration data to flash. So I have planned the flash memory orientation like this:

#define FLASH_SIZE_KB                32
#define FLASH_END_ADDR          ( FLASH_SIZE_KB * 1024 )                            //Result: 32768

#define CAL1_SIZE                         ( sizeof(calibration1_t))                                  //Result: 104
#define CAL1_FLASH_ADDR         ( FLASH_END_ADDR - CAL1_SIZE )           //Result: 32664

#define CAL2_SIZE                         ( sizeof(calibration2_t))                                   //Result: 276
#define CAL2_FLASH_ADDR          ( CAL1_FLASH_ADDR - CAL2_SIZE )         //Result: 32388

This code snippet does not work properly. I also added the result of the calculations in the comment for you to check. 

Then I set the addresses to below (constant addresses) and it is working well now:

#define FLASH_SIZE_KB                32
#define FLASH_END_ADDR          ( FLASH_SIZE_KB * 1024 )

#define CAL1_SIZE                         ( sizeof(calibration1_t))
#define CAL1_FLASH_ADDR         32000     

#define CAL2_SIZE                         ( sizeof(calibration2_t))
#define CAL2_FLASH_ADDR          31000    

What do you think causes the problem in the first snippet? Why it does not work when I don't set constant addresses? My calibration structs are aligned as 4 bytes. So there should not be any problem with padding.

0 Kudos
855 Views
abdullah_cinar
Contributor III

I finally solved the problem. I found out that it is only allowed to write 1 sector of flash in a flash program routine. My flash addresses were corresponding to such an address that does not end up writing only 1 sector but writing some of the data to 1 sector and overflowing to the other sector. So I changed my code, I am calculating the addresses with respect to the sector sizes. I set each address to one of a sector start:


#define FLASH_SIZE_KB                           32

#define SECTOR_SIZE                              1024

#define FLASH_END_ADDR                       ( FLASH_SIZE_KB * 1024) 

#define CAL1_SIZE                                     ( sizeof(calibration1_t))

#define CAL2_SIZE                                     ( sizeof(calibration2_t))


CAL1_Addr = FLASH_END_ADDR - CAL1_SIZE;

/* Put the start address to the start of a sector (to prevent splitting the data to 2 sectors) */
if( (CAL1_Addr % SECTOR_SIZE) != 0)
   CAL1_Addr = CAL1_Addr - ( CAL1_Addr % SECTOR_SIZE );         //Result:    31744

CAL2_Addr = CAL1_Addr - CAL2_SIZE;

/* Put the start address to the start of a sector (to prevent splitting the data to 2 sectors) */
if( (CAL2_Addr % SECTOR_SIZE) != 0)
   CAL2_Addr = CAL2_Addr - ( CAL2_Addr % SECTOR_SIZE );         //Result:    30720