I would like to make a 1KB read-only memory segment in my Flash.
My chip is MK10DN512Z VLL10. It has PFLASH0 and PFLASH1 section, each having 256KB of data.
My lcf file looks like this:
and in my main file I did this:
then I called that myTest() function in my main file. But when I read from that memory segment, I see nothing is written to it!!!
Now once I do all this, I the xMAP file, I cannot see that my_factory sector is created (the pointer to linker file is generated only):
# .para_config
#>00004000 __PARACFG (linker command file)
Why is that?
The goal is to specify a read-only sector in my FLASH memory that my code can write to it only. Once the FW is up, no one can write to that segment.
Hello Mehdi:
I have some comments:
1- Your m_text and m_factory_params segments are overlapping, and they need to be separated. It is common to place configuration parameters at flash start or end.
2- You declare the array inside of a function. It is not necessary. Just declare the array alone.
3- In CPU processor expert build options, use "R" instead of "RX". The same for the section declaration.
4- As your array is in flash (read-only) use const instead of static.
5- In the main you put ".para_config". According to your lcf, this should be ".paraconfig".
5- You are declaring the array, but as it is not referenced from your code yet, the linker is being "smart" and ignoring that section. Use KEEP_SECTION to force the linker to place that section.
6- :smileyalert: Once you modify the linker file, you need to disable linker file generation from CPU processor expert component. It is in the "Build options" tab.
With all that being said, here is how I would achieve your need:
- In the LCF file:
KEEP_SECTION { .vectortable }
KEEP_SECTION { .cfmconfig }
KEEP_SECTION { .paraconfig }
MEMORY {
m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x000001E0
m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x0007F7F0
m_data (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x00010000
m_data_20000000 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00010000
m_factory_param (R) : ORIGIN = 0x0007FC00, LENGTH = 0x00000400
m_cfmprotrom (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
}
SECTIONS {
## Heap and Stack sizes definition
__heap_size = 0x0400;
___stack_size = 0x0400;
.para_config :
{
__PARACFG = .; # start address of the new parameter configuration sector.
. = ALIGN(0x4);
* (.paraconfig) # actual data matching pragma directives
. = ALIGN(0x4);
} > m_factory_param
- In your code:
#pragma define_section para ".paraconfig" abs32 R
__declspec(para)
const uint8_t se_mee[0x10] =
{
0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U,
0x09U, 0x0Au, 0x0BU, 0x0CU, 0x0DU, 0x0Eu, 0x0FU, 0x00U
};
/*lint -save -e970 Disable MISRA rule (6.3) checking. */
int main(void)
/*lint -restore Enable MISRA rule (6.3) checking. */
{
Hope this helps you.
Regards!
Jorge Gonzalez
Thank you Jorge,
Okay so this is what I am going to do:
1- since I will be implementing switch feature for FW update, I need PFLASH1 section for future use. So I am not touching that section.
2- As you suggested, I specify the last KB of my PFLASH0 as factory values. It starts at address 0x0040_0000.
3- I follow your fixes to my linker file and change RX to R. Once I adjust my linker file and main code, I printf those memory values.
linker file:
and below is my code:
#pragma define_section para ".paraconfig" abs32 R
__declspec(para)
const uint8_t factory_values[3] = {
0x01,
0x02,
0x03
};
/*lint -save -e970 Disable MISRA rule (6.3) checking. */
int main(void)
/*lint -restore Enable MISRA rule (6.3) checking. */
{
/* Write your local variable definition here */
/*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
PE_low_level_init();
/*** End of Processor Expert internal initialization. ***/
/* Write your code here */
printf("factory param0 = 0x%x\n", IO_READ32(0x00040000));
printf("factory param1 = 0x%x\n", IO_READ32(0x00040001));
printf("factory param2 = 0x%x\n", IO_READ32(0x00040002));
printf("factory param3 = 0x%x\n", IO_READ32(0x00040003));
printf("factory param4 = 0x%x\n", IO_READ32(0x00040004));
}
the printf shows me:
factory param0 = 0x30201
factory param1 = 0xff000302
factory param2 = 0xffff0003
factory param3 = 0xffffff00
factory param4 = 0xffffffff
I would expect to see param0 to be 0xff030201, and the rest of registers to stay 'ff' all?