Correct to use _RODATA(Flash2) to define "variable" data in flash?

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

Correct to use _RODATA(Flash2) to define "variable" data in flash?

1,810 Views
mci
Contributor III

*MCU = MKL28Z512VLL7  (has 512KB flash memory built-in)

*IDE = MCUXpresso

*Debugger = PEMicro Multilink

*Custom target board

Hi,

I'm starting new & separate question from previous one about writing data to non-volatile memory, specifically MKL28Z's flash memory.

(Sorry I had to take a break from this operation last 1.5 weeks because I got pulled-back to the Touch Sensing operation of the project to deal with "materials" dielectric constants surrounding our touch electrode which cause unwanted self-capacitive touch triggers, besides just finger tip touch...)

Inside MCUXpresso, this image below is my partitioned Memory details, as shown on image.   In MKL28Z, for its built-in 512KB Flash, I keep 508KB for code & just assign 4K for data variables that need to be kept in non-volatile memory for safe-keeping in case of power failure, we don't want to lose latest measurements data.

MKL28ZflashPartition1.jpg

Technical support mentioned about using a macro called,  _RODATA(Flash2), to define a variable in that section.

This is not self-explanatory to me given an example post about this as also stated on MCUXpresso IDE User Guide.  It is not clear because if I read their statements literally which mention "constant", then that says to me that "RO" means "read-only".  (see https://community.nxp.com/thread/389102)

Questions:

1) Does the "RO" in RODATA mean "read-only"?   I need my variables to be changeable to different values that can be updated whenever statistical measurements of the system are gathered periodically.

2) The posted discussion did not provide the "memory map" as I showed on image above.  And they say some other or additional flash memory block added from other external flash or block.   I got 2 flash sections by simply splitting up what used to be all 512KB  "PROGRAM_FLASH_512" & Aliased "Flash" and changing the address & size range accordingly.   Is their discussion applicable & similar anyway to my situation?

3)  Having no memory map shown like my image above, I'm not sure if the Alias term, "Flash2" is coincidental as used in _RODATA(Flash2).   If "Flash2" is exactly whatever alias or name was assigned for the "other or new" flash memory area to be used for data (or function as posted), then I guess I should also use "Flash2" as in _RODATA(Flash2) ...?

4) The post stated to include as:

#include <cr_section_macros.h>

Include where?  In my own header .h or source .c file?

5)  If so, with _RODATA(), there is no need for me to hardcode or program any #definition like starting & ending address of my Flash2 data section in flash?

E.g.

#define  DATA_FLASH_4_START_ADDR   0x0007F000U

#define  DATA_FLASH_4_ENDING_ADDR   0x0007FFFFU   (correct?  or less 4-byte alignment must be 0x0007FFB ?)

6) Without the need for hardcoding direct address definitions of start & ending address for that section in flash, does defining a string will automatically put that string definition inside Flash2 section without worries?

 _RODATA(Flash2) char str[] = "hello world\r\n";

7) Where does flash memory "protection" and "secured" settings come into play in all these?     During flash (code) programming, I don't want my stored data in Flash2 to be erased or overwritten.   Should I be setting up FPROT registers for that area in memory to prevent my data area from being deleted or corrupted?  Where in code should I set FPROT registers to protect my data flash area from flash erase & programming (inside MCUXpresso or external flash IC programmer)?

8) MKL28Z flash memory is 2KB size sectors.    To write values to the flash data area, a whole 2KB section first needs to be erased & verified as erased.    However, I may already have some previously saved data values within that sector even though I'm only changing one of the variables now, which so happen to have a size of 1 byte only.  The best practice for this situation would be during program initialization when data variables are placed in RAM space (.data or .bss, initialized or zeroed out).    How do I make "a copy" of my data (2K+2K=4K) from Flash2 be copied in RAM space for volatile fast access?  And so when it's time to save an update to one of the bytes or word variables to non-volatile flash, AFTER ERASE of 2KB sector, I can RESTORE all the full 2KB values from RAM & write them to flash.  Is that correct method to do this?

That's all for now.

Thank you very much for your help.

MI

Labels (1)
0 Kudos
8 Replies

1,427 Views
mci
Contributor III

Hi Jing,

Thanks for your help.

I found also some help on my question/post at this link.   You are free to check it out because it is RELATED to this post of mine too.

https://community.nxp.com/thread/510817

Regards,

MI

0 Kudos

1,427 Views
mci
Contributor III

Hi Jing,

Thanks for all your help.

I've decided to do the way I understand how it is to be done & not rely on toolchain, linker, macros and such memory mapping arrangement.   

Since I know the exact address where I want to place my read/program data structures, I went for what I talked about before - by #define ADDRESS_START...  and such "hardcoding" direct addressing.

I finally got to build such restructuring independent of __RODATA, __TEXT & such, without errors & warnings, i.e.

16:35:24 Build Finished. 0 errors, 0 warnings. (took 12s.6ms)

I'm not proceeding to testing the code.

As an aside, even though I'm not using any cr_macros…,  do you know if the MCU setting split-up of Flash from 512KB to 508KB Flash & 4KB Flash2, necessary?

Comments are welcome.

Thanks again,

MI

0 Kudos

1,427 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi,

It's hard to say necessary. But I think it is useful. If the main application image is bigger than 508k, this can make the compiler report error.

Regards,

Jing

0 Kudos

1,427 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi,

10) Please read cr_section_macros.h. You'll find there is nothing special. NXP only write some definition to convenience customer.
#define __TEXT(bank) __SECTION(text, bank)
#define __SECTION(type, bank) __attribute__ ((section("." #type ".$" #bank)))

So, this will not have any influence to following code. This is GNU C/C++ compiler grammar.

11)MCUxpresso can dump code easily.pastedImage_1.png

Regards,

Jing

0 Kudos

1,427 Views
mci
Contributor III

Hi Jing,

Yes, my settings are erase, verify blank, then program --- so all are erased first before the other steps.

I'm not very adepth with builders for image mapping and so I apologize if my questions may be wrong or dumb.  Thanks for your patience and understanding.

More follow-up:

10)  I understand that "text" is code, while DATA, RODATA, BSS... are for different data mapping.  Your _TEXT(Flash2) definition made this char string resident in code area, so even if the MCUXpresso or Cyclone programmer ERASES flash first before programming, having _TEXT(Flash2) defined will also make that "data" get PROGRAMMED like as part of code?  

Which of these understanding is correct or what really happens? 

a. Since you defined _TEXT(Flash2) char tt... at the top of pflash.c, will the following lines of code be after it?  And so will tt data, together with lines of code following it be up there residing in flash address starting at 0x7f0000?

b. Or, ONLY "tt" will be up there in 0x7f000, while the following code lines will fall normally at the lower flash code area block 0. 

c.  If b is true, will there be  BIG empty flash are GAP in-between the end of code in lower part of Flash (after vector table) and my Flash2 "tt" data area?

11) After build &/or during debugging, is there a way or a "tool" in MCUXpresso to do a HEX (&ASCII) DUMP that displays all parts of MKL28Z memory while display the rows & columns of the contents for address starting 0x00000000 thru 0x80000 or however I will be able to view current values from this to that address in memory?   (Similar to Windows "debug" command that displays contents of memory in your program or your PC, by default).

Thanks again for your help.

MI

0 Kudos

1,426 Views
mci
Contributor III

Hi Jing,

I see what you did.   Thanks for this great example project.   I'll study it & see how I can use for my application.   I'll probably be using data structures.   And I plan to load a copy of this in SRAM for high frequency read-write access and will decide how often I will have to save to ensure data is in non-volatile memory in case of brown-out, etc...

I'm going to trace through this step-by-step (like I have done with original pflash.c project.   I'll do that TO CONFIRM if "destination" address is actually going to address 0x7F000.   Browsing through your code, I did not catch if "tt" falls in that area.

FOLLOW-UP question regarding 0x7F000 flash area & above (4KB) will not get overwritten whenever "flash-programming" code into the chip.

Is this understanding of mine correct? (I haven't investigated the linker memory map result)

9)   In general, does MCUXpresso or any IC programmer only erase that section of flash memory where the full binary image will be programmed into?   Or does it erase the WHOLE 512KB flash area before programming?

& I will have DEFAULT DATA values in my Flash2 area.

    a)  If knowing to erase only that amount of flash area needed to program code, then I don't have to worry about protecting Flash2 data area, correct?

    b)  If erasing all 512KB before programming, how do I program back both code at lower flash space  + default data values at the last 4KB of flash memory?

Thanks again for your help.

MI

0 Kudos

1,427 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi,

You can set if a mass erase should be done before program. Please set it in Run->Debug configurations->GUI Flash Tools.

Regards,

Jing

0 Kudos

1,428 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi,

1. yes, RODATA is ready-only data. But here you can't use __RODATA(Flash2) to declare data in Flash2. __RODATA is also data! It will be initialized when program start. This 4k space is in flash area. You can only read it. You can't write it by
"foo=0x11;"

This will cause hardfault! You split flash in software level, not in hardware level.
If you declare it as a __DATA() or __BSS(), initialize code will try to write something into it also.  
You can only declare as "__TEXT(Flash2)".

2. you can do that. No problem.

3. Flash2 is alias of DATA_FLASH_4. They are same. Both __RODATA(Flash2) and __RODATA(DATA_FLASH_4) is correctly. But again, you can't use __RODATA(Flash2).

4. When you use __RODATA() or __BSS() or __NOINIT(), you should add this line in the file.

5,6. You can define
#define  DATA_FLASH_4_START_ADDR   0x0007F000U
#define  DATA_FLASH_4_ENDING_ADDR   0x0007FFFFU
This will not affect compiler. You can read Flash2 by pointer. You can program Flash2 by FLASH_Program() function. Defining DATA_FLASH_4_ENDING_ADDR to 0x0007FFFFU has no meaning to hardware or compiler. It only has meaning to you. You know if you read or write over this limit, hardfault will happen. If you have (*(unsgiend int*)DATA_FLASH_4_ENDING_ADDR)=xx, alignment hardfault will also happen.

7. "Secure" means all flash memory can't read/write from external port. "Protection" means individual regions within the flash memory can be protected from program and erase operations. If you set FPROT, you can't erase/write it anymore. It seems conflict with question 1.

8. Kinetis flash cycling endurance minimum is 10k. That means you can only erase-write 10k times. If the erase-write operation is in a low frequency, it is fine. But if you often do it, you must take it into consider.

I made a demo to show how to use Flash2. You can see that I declare a __TEXT(Flash2) address variable, print it, then modify it by flash erase/write function. Then print it again. It will print out new value.

Regards,

Jing

0 Kudos