Unable to write to MK60 internal Flash if a variable is declared in the section

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

Unable to write to MK60 internal Flash if a variable is declared in the section

Jump to solution
1,796 Views
LRawlyk
Contributor III

I am using the the NXP MK60FN1M0VLQ12 and I have some variables I want to store in the internal Flash, so I declared a separate section in the linker script and a global struct in it to be referenced by the code. Then to program it I use a slightly modified version of Processor Expert's FMC driver to erase the sector then program 8 bytes at a time.

However, whenever the global variable is declared, I fail to erase/program the flash, and otherwise it works fine. Of course the easy workaround in this case is to use a pointer to the section, but I also plan to rewrite a code section, where this wouldn't work. Does this have to do with the C linker/compiler or is it a MK60 or driver thing?

Here are the concerned code slices:

Linker script:

m_status_page (RX) : ORIGIN = 0x00040000, LENGTH = 0x00001000

.status_page : { . = ALIGN(4); KEEP(*(.STATUS_PAGE)) . = ALIGN(4); } > m_status_page

Global variable declaration:

StatusPage _status_page[TOTAL_STATUS_PAGE_NUMBER] __attribute__ ((section (".STATUS_PAGE")));

Then when I do the execute the following command it does nothing and doesn't throw an error:

flashProgram8Bytes(bytes_to_program, _status_page);

But if I don't declare the _status_page variable for example the following command works:

flashProgram8Bytes(bytes_to_program, 0x00040000);

Labels (1)
0 Kudos
1 Solution
1,725 Views
Daniel-Aguirre
NXP TechSupport
NXP TechSupport

Looking deeper in the RM, it is told that " A write operation to program flash memory or to data flash memory results in a bus error. " [Page 585, K60 Sub-Family Reference Manual, Rev. 6.1, Aug 2012].

The FMC seems to be more of a read acceleration for Program and Data Flash Memory, but does not have the capabilities to write to them.

Seems strange that you can write using FMC, but that could be why they are getting 0 initialized.

As a summary, seems to be more of a MK60 platform related.

Please, let us know if this information is helpful or not

View solution in original post

0 Kudos
9 Replies
1,758 Views
LRawlyk
Contributor III

I actually just realized something I should've before.

When I declare a variable in the section it's getting 0 initialized. If I declare an uint32_t I'm getting 4 bytes 0 initialized, if I declare an uint32_t[2] I get 8 bytes, and so on.

However I don't know if this is normal and what's the link to not being able to erase or program the flash...

 
0 Kudos
1,793 Views
ErichStyger
Senior Contributor V

Not sure what your flashProgram8Bytes() does, but if you have data in it, does it perform an erase first?

What if you do that in your code too (erase first)?

0 Kudos
1,789 Views
LRawlyk
Contributor III

flashProgram8Bytes() is just an interface to call the Flash driver functions:

 

LDD_TError flashEraseSector(uint8_t sector_number)
{
LDD_TError err;
err = FMC_EraseSector(sector_number);
if (err == ERR_OK)
return flashPerformOperation();
else
return err;
}

LDD_TError flashEraseBlock(uint8_t block_number)
{
LDD_TError err;
err = FMC_EraseBlock(block_number);
if (err == ERR_OK)
return flashPerformOperation();
else
return err;
}

LDD_TError flashProgram8Bytes(uint8_t* source_ptr, LDD_FLASH_TAddress destination_ptr)
{
LDD_TError err;
err = FMC_Write8Bytes(source_ptr, destination_ptr);
if (err == ERR_OK)
return flashPerformOperation();
else
return err;
}

LDD_TError flashPerformOperation(void)
{
LDD_FLASH_TOperationStatus status;
status = FMC_PerformOperation();
if (status == LDD_FLASH_DONE)
{
status = FMC_GetOperationResult();
if (status == LDD_FLASH_IDLE)
return ERR_OK;
else
return ERR_FAILED;
}
else
return ERR_RANGE;
}

 

I am erasing the Flash first. The real code is more complicated than this, but what I'm doing is basically:

 

flashEraseSector((uint32_t)_status_page / MK60_FLASH_SECTOR_SIZE);

uint8_t bytes_to_program[8];

for (int i=0; i < data_size; i+=8)

{

    initialize_bytes();

    flashProgram8Bytes(bytes_to_program, _status_page + i);

}

 

The flash remains untouched after erases and program commands like this, but it works fine if I remove the _status_page declaration and replace it with 0x00040000 for example.

0 Kudos
1,769 Views
Daniel-Aguirre
NXP TechSupport
NXP TechSupport

Hi,

Could be a long shot, but have you tried change the attributes of the section to WX (Read/Write and Executable).

Maybe trying to erase a Section with the Read-Only attribute gives an error.

Again, could be a long shot.

Let us know if this helps with your problem.

0 Kudos
1,761 Views
LRawlyk
Contributor III

Hello, no this is a legitimate try, but I've already tried it without success.

0 Kudos
1,757 Views
Daniel-Aguirre
NXP TechSupport
NXP TechSupport

You are telling that when sending the value as a constant (without the label), works.

What if instead of just putting the label, you send it through a function that returns the constant value. That could also help to understand if the linker if taking the label as the 0x00040000 value.

Instead of

flashEraseSector((uint32_t)_status_page / MK60_FLASH_SECTOR_SIZE);

Could be

flashEraseSector((uint32_t) returnAsConstant(_status_page) / MK60_FLASH_SECTOR_SIZE);

Again, could be another long shot.

0 Kudos
1,746 Views
LRawlyk
Contributor III

From I can see the way the parameter is passed to the driver function has no effect in making it work or not.

When I declare a variable in the section, whether I point to the variable or I use the section address directly (0x00040000 in this case), the variable gets 0 initialized and I can't erase or program the flash. And when it isn't declared it works, but of course in this case I use an address since the variable isn't declared.

0 Kudos
1,726 Views
Daniel-Aguirre
NXP TechSupport
NXP TechSupport

Looking deeper in the RM, it is told that " A write operation to program flash memory or to data flash memory results in a bus error. " [Page 585, K60 Sub-Family Reference Manual, Rev. 6.1, Aug 2012].

The FMC seems to be more of a read acceleration for Program and Data Flash Memory, but does not have the capabilities to write to them.

Seems strange that you can write using FMC, but that could be why they are getting 0 initialized.

As a summary, seems to be more of a MK60 platform related.

Please, let us know if this information is helpful or not

0 Kudos
1,680 Views
LRawlyk
Contributor III

That's interesting because we've had applications developed that fully rely on the FMC writing to program flash for firmware upgrade purposes (using the workaround to not define variables in the section or to not define sections at all). That seems to be a bug turned into a feature then...

0 Kudos