Flash protect feature

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

Flash protect feature

2,020 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Well:

1) It is optional. abs32 is the addressing mode. The linker addresses this section with 32 bits. R is also optional, and this indicates the access type for the section, in this case read. If you want to learn more about this, give a check to the MCU_Kinetis_Compiler.pdf in your CodeWarrior installation:

C:\Freescale\CW MCU v10.5\MCU\Help\PDF

2) You still need to protect that section. The "R - READ" feature is only for the application, I mean that this R tells the compiler to treat the section as read-only. In other words, you are only preventing your code from writing to that section, but it does not mean that the physical memory is protected.

Check the next application note for some basics about security:

http://cache.freescale.com/files/microcontrollers/doc/app_note/AN4507.pdf

Regards!

Jorge Gonzalez

21 Replies

1,159 Views
mehdikarimibiuk
Contributor V

Hi Jorge,

I have a question about your second comment: "R tells the compiler to treat the section as read-only". Is this is true, so my application would not write to it, correct?


If I set that region to "PROTECT", it means physical protect, so it means it cannot be written from outsiders?

I thought this can be done by SECURITY?

Please comment about this.

What I want to do: I want to write to that section at the beginning of my code, then set it to read-only from everybody.

If I set to R for that region in my linker file, that should work for my application only. If I choose security would that also protect it from outsiders? how about protect? what is the difference between the two, I am a bit confused for the differences between these two!

Thanks!

Mehdi

0 Kudos

1,159 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Medhi:

Here is some explanation:


Protect: The selected segments of flash are protected from program or erase operations, either by the application itself or by external tools.


Secure: The flash memory cannot be accessed with an external tool. The only way to recover access to the flash from the outside is with a mass erase. This is to prevent someone trying to read the code in your device, to reproduce it or something similar. With this option, your application can still write or erase flash.


So, if you protect some segments of your flash, then your application will not be able to write to those segments. But if you just secure flash, then this avoids external access, but your application mantains read/write access to flash.

Hope this clarifies a little more.


Regards,
Jorge Gonzalez

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

1,159 Views
mehdikarimibiuk
Contributor V

Ok so in linker file, this R set the read-only during compile time?

" m_factory_param (R) : ORIGIN = 0x0003C000, LENGTH = 0x00000400"

that means that during compile time codewarrior will not write to that location.

and so during run-time I have to use "SetProtection" from API to protect that location from writing during run-time?

0 Kudos

1,159 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Yes, I think your understanding is correct. The R only applies to compile-time, not run-time. You can use the SetProtection API to protect the desired areas.

0 Kudos

1,159 Views
mehdikarimibiuk
Contributor V

Hi Jorge, thanks for sending me the document.

I went through that document.  [As a reference my chip is MK10DN512Z VLL10].

But before discussing the document, I have a leftover question:

1- There are two lcf files I found in the project:

     one is at "project root"->"project headers"->project settings->linker files

     and the other is in "project root"->project settings->linker files

     do i need to edit both?

2- Now back to the document: When I get into debug mode, for FTFL device, I see registers 0x4002_0010 to 0x4002_0013 for protect. Would writing to these registers by using the FLASH_LDD API methods, set the protect registers located in flash configuration field (registers: 0x0000_0408 to 0x0000_040b)?

3- If I write to FTFL_FSEC (register 0x4002_0002), would it configure NV_FSEC (register 0x0000_040C)?

If 2 and 3 are true, then why not writing to those config. field registers directly to configure protect and security features?

4- At the moment, I do not need FSEC. I only would need protect field. For that factory values (the last 1KB of PFLASH0)  that I told you, I would make them protect, so no one from outside can change them, only reading them are allowed.

As you showed me, I was able to make that section of the memory read-only for the linker not to write to that region and also I would need to protect it to prevent outsiders or even my FW to write to that section. Only read allowed.

5- It is interesting that the FLASH API available in PE has write/read/erase methods. It allows reading and writing conveniently from/to sections of my Flash. But I was thinking, I already have macros like IOREAD and IOWRITE that do the same thing!? Unless I want to use the FTFL registers. Otherwise, I can directly access flash config. registers?

0 Kudos

1,159 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Medhi:

No problem.

About your questions:

1) That is strange. I do not know how you got a pair of linker files. There should be only one located in "project root -> project settings -> linker files". To be sure which one the linker is considering, go to Project -> Properties -> C/C++ Build -> Settings -> ARM Linker -> Input; and in "Linker Command File" you will see the path to the correct lcf file.

2) and 3): The other way around. You need to write to the non volatile registers in flash (0x0000_0408 to 0x0000_040b), and during reset sequence the MCU automatically copies those values to ram registers (0x4002_0010 to 0x4002_0013). In your lcf file you can find a predefined section called "cfmconfig". That section is for the flash configuration field. In a normal project you would need to declare an array with your required values to store them in that section, exactly like you did for your custom read-only section. But in this case with processor expert is easier. Just go to your Cpu component properties -> Internal peripherals -> Flash configuration field -> Protection regions. This will modify the array already declared in "Generated_Code -> Cpu.c". The array is called _cfm[].

PE_Protect.png

5) Not sure I understand your question 5. The methods provide flexibility. You can specify an address and the size of data to be read.

About your macros, IOREAD is easy, just reading memory with a pointer, but what about IOWRITE, you use this for flash or just for ram?

1,159 Views
mehdikarimibiuk
Contributor V

1) yes that is the correct path. I checked by going into project properties. Thanks for that.

2-4) I believe using the PE GUI is the best way to configure sections so there is no need using API write function.

I made the last section of my PFLASH0 to be protected:

5) IOWRITE is like this:

#define IO_WRITE32(addr, value) (*(volatile UINT32 *)(addr) = ((UINT32)(value)))

so I believe it can write to any address.

0 Kudos

1,159 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hi Mehdi:

Yes, with the GUI is easier to protect your flash.

Just to clarify, your IO_WRITE macro can write to any address in ram, but not in flash. You need the FLASH_LDD write API for writing.

Regards!

Jorge Gonzalez

1,159 Views
mehdikarimibiuk
Contributor V

Why is that my write macro cannot write to flash? The whole addressing space is contiguous and so it should not be a problem to write to any address as long as that address is write-enable.

Mehdi

0 Kudos

1,159 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hi Mehdi:

Writing to flash is not as simple as "pointing to adress" and "writing". The MCU has an internal flash controller that performs algorithms to erase and write to flash. But the controller is based on commands, which must be triggered by the user (*you). All the explanation is in the Flash Memory Module part (in your case i think it is chapter 29) of the reference manual.

That is why the Flash API does all the work for you, sending the appropriate commands.

/Jorge Gonzalez

1,159 Views
mehdikarimibiuk
Contributor V

Hi Jorge,

When I write to flash and read back, I get nothing...Is there any other preparation that I need to make for write and read for flash?

Here is what I did:

LDD_TDeviceData *Program_Flash;

int main() {

UINT16 data;

UINT16 buff_test;

UINT32 ADDR;

Program_Flash=ProgramFlash_Init(NULL);

data = 0x1234;

ADDR = 0x00010000;

ProgramFlash_Write(Program_Flash, &data, ADDR, sizeof(data));


printf("#######\nread from memory start address 0x%x\n", ADDR);


ProgramFlash_Read(Program_Flash, ADDR, &buff_test, sizeof(buff_test));

printf("buff_test = 0x%x\n#########\n", buff_test);

}

and here is the prints:

#######

read from memory 0x10000

buff_test = 0x1fff

#########

I am not reading back the values that I put in that address forward!!! Why?

0 Kudos

1,159 Views
mehdikarimibiuk
Contributor V

I FORGOT TO ENABLE INTERRUPT in my flash ldd component view in PE. It works now. Thanks alot!

I see that my event is not being triggered, why?

main {

printf("ADD = 0x%x HEX = START AT %d KB.\n", ADDR, ADDR/1024);
ProgramFlash_Write(Program_Flash, &data, ADDR, sizeof(data));
//err = ReadFlash(Program_Flash, ADDR, buff_test, sizeof(buff_test));
while (!DataWrittenFlg) {
printf("DataWrittenFlg = 0x%x \t", DataWrittenFlg);
}
ProgramFlash_Read(Program_Flash, ADDR, &buff_test, sizeof(buff_test));
printf("buff_test = 0x%x\n#########\n", buff_test);

}

void ProgramFlash_OnOperationComplete(LDD_TUserData *UserDataPtr)

{

  /* Write your code here ... */

  DataWrittenFlg = TRUE; /* Set DataWrittenFlg flag */

}

DataWrittenFlg is not being set to true at any time and I end up in that while loop forever! I don't know why!!!


1,159 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Good to know is working now Mehdi.

When in doubt on how to use the component APIs, right click on the component and select "Help on component". You will see the explanation for every method, property and even some code examples using the APIs.

Help.png

In this case, if you do not enable the interrupt, you need to periodically call the method ProgramFlash_Main().

/Jorge

1,159 Views
mehdikarimibiuk
Contributor V

Thanks Jorge.

One thing I also notice is that when we write to the flash we cannot overwrite it. Is this true? So we have to erase and then write again if we want to?

0 Kudos

1,159 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

That is true Mehdi.

The "blank/erased" state of any byte in flash is "FF" (all '1's), and bits can only change from 1 to 0, not the other way. That is why if you want to write to the same byte, first the bits need to be erased back to '1'. Also, please note that you cannot erase individual bytes, the smallest erase size is 2 KB in your case (flash sector size).

/Jorge

1,159 Views
mehdikarimibiuk
Contributor V

Ok! sounds good then!

Reading from the help, I see there are two Erase methods, one is Erase and the other is EraseBlock. I believe the one that you are referring to is Erase. And so the EraseBlock would erase the whole PFLASH. Does EraseBlock erase both PFLASH0 and PFLASH1 blocks?

What if I have set sections of my flash as protected, are they going to be erased too?

0 Kudos

1,159 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Correct. EraseBlock() would erase whole PFlash0 or whole PFlash1. This depends on the address you give it. If the address belongs to PFlash0, then PFlash0 is erased, and if address is inside PFlash1, then PFlash1 is erased. If you have sections protected, then those sections should not be erased.

The Erase() method only erases 2KB sectors, not whole blocks.

/Jorge

1,159 Views
mehdikarimibiuk
Contributor V

Hi Jorge,

When I use the erase method, just to test it, I do this sequence: erase, write, and read.

Like below:

this sequence does not work, in fact, it stucks in the first erase do-while loop. I am not sure how I can use this erase method. Am I using it incorrectly? Would you suggest a better option to do this?

All I want to do is to erase the sector where that ADDR is located then write and read. This is just a test, I want to see this erase works!!

0 Kudos

1,159 Views
mehdikarimibiuk
Contributor V

Hi Jorge,

Do you know of any way that I can use this Erase functions since it is not working the way I implemented above, I tried a few other conditions with it, but it still is not working, do you know how I can implement this?

Thanks

Mehdi

0 Kudos

1,159 Views
mehdikarimibiuk
Contributor V

yeah, I am a bit confused about how erase function works, I tried a number of different ways and conditions but it did not work, do you have any clue?

0 Kudos