Problem with Erase Flash memory

cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with Erase Flash memory

Jump to solution
2,537 Views
luca_securo
Contributor III

Hi to all,

I'm trying to read and write in flash memory with the new mkl33z64 microprocessor.

I had import an SDK flash's example for kl43. I had copy the function in my main I compiled it and it's ok.

I started to debug and the debugger stopped always during FLASH_Erase() inside the function ftfx_command_sequence(ftfx_config_t *config) in particular it stopped in this point: callFtfxRunCommand((FTFx_REG8_ACCESS_TYPE)(&FTFx->FSTAT)); 

This function is inside the driver fsl_ftfx_controller.c

I can't understand what happened. What's wrong?

Thank you for help.

Luca

Labels (1)
1 Solution
1,254 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Luca,

I use FRDM-KL43Z board with SDK provided [pflash] demo, when debug the code into ftfx_command_sequence() function code  in <fsl_ftfx_controller.c> file.

You will find below code and the callFtfxRunCommand call the code at RAM:

pastedImage_1.png

In previous reply, I mentioned the FTFx_DRIVER_IS_FLASH_RESIDENT macro definition will copy Flash run command function to RAM.

Below is the s_ftfxRunCommandFunctionCode[] assembly instruction, which function is same with below C code, you could found at AN4695:

pastedImage_2.png

When you debug the code, you could find the same data located at RAM address 0x1fffe0e0:

pastedImage_3.png

The ftfx_command_sequence() function will call these assembly instruction when run Flash command.

Wish it helps.


Have a great day,
Mike

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

View solution in original post

11 Replies
1,254 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Luca,

If you had macro definition of FTFx_DRIVER_IS_FLASH_RESIDENT?

If yes, please check below code at <fsl_ftfx_controller.c> file to copy flash_run_command() to RAM

#if FTFx_DRIVER_IS_FLASH_RESIDENT
/*!
 * @brief Copy PIC of flash_run_command() to RAM
 */
static void ftfx_copy_run_command_to_ram(uint32_t *ftfxRunCommand)
{
    assert(sizeof(s_ftfxRunCommandFunctionCode) <= (kFTFx_RamFuncMaxSizeInWords * 4));

    /* Since the value of ARM function pointer is always odd, but the real start address
     * of function memory should be even, that's why +1 operation exist. */
    memcpy((uint8_t *)ftfxRunCommand, (const uint8_t *)s_ftfxRunCommandFunctionCode, sizeof(s_ftfxRunCommandFunctionCode));
}
#endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */

The Flash run command should be execute at RAM to avoid  read while write violations.

More detailed info, please check AN4695.


Have a great day,
Mike

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

1,254 Views
luca_securo
Contributor III

Hi Mike,
thanks for your answer.
I read all the document that you attached.


In my project there are all you wrote:
- The definition of FTFx_DRIVER_IS_FLASH_RESIDENT is 1
- Ftfx_copy_run_command_to_ram() is inside FTFx_API_Init() called by FLASH_Init and I called it (like the example)

I’m using :
- the SDK example who I imported in my workspace. I imported “driver example” > “flash”
- MKL33Z64, it has only one block of FLASH.
- MCUXpresso IDE


I think that everything is all right but It doesn't work.
Do you have any other suggestions?

PS  I'm working with a custom board, I can't test the SDK example projects.


Thank you!
Luca

0 Kudos
1,254 Views
luca_securo
Contributor III

Hi, today I understood how to modify the linker file with MCUXpresso using "MCU settings"

Now I have two partitions of FLASH and two of RAM.

I had implement this macro:

#define __relocate_code__ __attribute__((section(".myRAM"), long_call))

To define .myRAM I used the "Extra linker script input section" 

I found it in Properties -> Settings -> MCU Linker -> Managed Linker Script

This is the right way isn't it?

But It doesn't work.

Maybe I have no understand how to use the macro "__relocate_code__" properly

I attach here the code:

void FlashMemoryInit(void)__relocate_code__;

void FlashMemory(void) __relocate_code__;

********************************************************

void __relocate_code__ FlashMemoryInit(void){
//Clean up Flash, Cache driver Structure
memset(&s_flashDriver, 0, sizeof(flash_config_t));
memset(&s_cacheDriver, 0, sizeof(ftfx_cache_config_t));

//Setup flash driver structure for device and initialize variables.
result = FLASH_Init(&s_flashDriver);
if (kStatus_FTFx_Success != result)
{
error_trap();
}
//Setup flash cache driver structure for device and initialize variables.
result = FTFx_CACHE_Init(&s_cacheDriver);
if (kStatus_FTFx_Success != result)
{
error_trap();
}
//Get flash properties
FLASH_GetProperty(&s_flashDriver, kFLASH_PropertyPflash0BlockBaseAddr, &pflashBlockBase);
FLASH_GetProperty(&s_flashDriver, kFLASH_PropertyPflash0TotalSize, &pflashTotalSize);
FLASH_GetProperty(&s_flashDriver, kFLASH_PropertyPflash0SectorSize, &pflashSectorSize);

//Check security status.
result = FLASH_GetSecurityState(&s_flashDriver, &securityStatus);
if (kStatus_FTFx_Success != result)
{
error_trap();
}

//Print security status.
switch (securityStatus)
{
case kFTFx_SecurityStateNotSecure:
//PRINTF("\r\n Flash is UNSECURE!");
break;
case kFTFx_SecurityStateBackdoorEnabled:
//PRINTF("\r\n Flash is SECURE, BACKDOOR is ENABLED!");
break;
case kFTFx_SecurityStateBackdoorDisabled:
//PRINTF("\r\n Flash is SECURE, BACKDOOR is DISABLED!");
break;
default:
break;
}
}

*********************************************************************

void __relocate_code__ FlashMemory(void)
{

// Test pflash basic operation only if flash is unsecure.
if (kFTFx_SecurityStateNotSecure == securityStatus)
{
/* Pre-preparation work about flash Cache/Prefetch/Speculation. */
FTFx_CACHE_ClearCachePrefetchSpeculation(&s_cacheDriver, true);

#ifndef SECTOR_INDEX_FROM_END
#define SECTOR_INDEX_FROM_END 1U
#endif

destAdrss = pflashBlockBase + (pflashTotalSize - (SECTOR_INDEX_FROM_END * pflashSectorSize));

result = FLASH_Erase(&s_flashDriver, destAdrss, pflashSectorSize, kFTFx_ApiEraseKey);
if (kStatus_FTFx_Success != result)
{
error_trap();
}

// Verify sector if it's been erased.
result = FLASH_VerifyErase(&s_flashDriver, destAdrss, pflashSectorSize, kFTFx_MarginValueUser);
if (kStatus_FTFx_Success != result)
{
error_trap();
}
//Successfully Erased Sector 0x%x -> 0x%x\r\n", destAdrss, (destAdrss + pflashSectorSize));

/////////////////////////////////
//Prepare user buffer to save in FLASH
for (i = 0; i < BUFFER_LEN; i++){
s_buffer[i] = i;
}
//////////////////////////////////

result = FLASH_Program(&s_flashDriver, destAdrss, (uint8_t *)s_buffer, sizeof(s_buffer));
if (kStatus_FTFx_Success != result){
error_trap();
}

//Verify programming by Program Check command with user margin levels
result = FLASH_VerifyProgram(&s_flashDriver, destAdrss, sizeof(s_buffer), (const uint8_t *)s_buffer, kFTFx_MarginValueUser,
&failAddr, &failDat);
if (kStatus_FTFx_Success != result){
error_trap();
}
// Post-preparation work about flash Cache/Prefetch/Speculation.
FTFx_CACHE_ClearCachePrefetchSpeculation(&s_cacheDriver, false);

#if defined(FSL_FEATURE_HAS_L1CACHE) && FSL_FEATURE_HAS_L1CACHE
L1CACHE_InvalidateCodeCache();
#endif // FSL_FEATURE_HAS_L1CACHE

#if defined(__DCACHE_PRESENT) && __DCACHE_PRESENT
// Clean the D-Cache before reading the flash data
SCB_CleanInvalidateDCache();
#endif

// Verify programming by reading back from flash directly
for (uint32_t i = 0; i < BUFFER_LEN; i++)
{
s_buffer_rbc[i] = *(volatile uint32_t *)(destAdrss + i * 4);
if (s_buffer_rbc[i] != s_buffer[i])
{
error_trap();
}
}

//PRINTF("\r\n Successfully Programmed and Verified Location 0x%x -> 0x%x \r\n", destAdrss,(destAdrss + sizeof(s_buffer)));

// Erase the context we have programmed before
// Note: we should make sure that the sector which will be set as swap indicator should be blank
FLASH_Erase(&s_flashDriver, destAdrss, pflashSectorSize, kFTFx_ApiEraseKey);

}else{
//Erase/Program operation will not be executed, as Flash is SECURE!
}

app_finalize();

}

That's all,

It's the copy of the example who I'm talking about today.

I could not go beyond the "FLASH_Erase" function.

Thank you for help

Best regards

Luca

0 Kudos
1,254 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Luca,

Sorry for the later reply.

Could you try to builder and download the MCUXpresso SDK software package for MKL33Z64xxx4 chip?

pastedImage_1.png

Then you could use MCUXpresso IDE to create a new project and porting [pflash] code to this new project:

pastedImage_2.png

Please try if the Flash "erase" command could be executed at your board?

Wish it helps.
Have a great day,
Mike

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

1,254 Views
luca_securo
Contributor III

Hi Mike,

  I did all you suggest to me.

The code who I attached 2 days ago is the pflash code (a little bit adapted to my project).

The erase comand didn't works.

Now I'm working on this way:

#include <cr_section_macros.h>

//execute these functions in RAM

__RAMFUNC(RAM2) void FlashEraseMemory(uint32_t addr);      //RAM2 is the partition made by myself using MCU Settings
__RAMFUNC(RAM2) void FlashWriteMemory(uint32_t addr);

__RAMFUNC(RAM2) void FlashEraseMemory(uint32_t addr){

   __disable_irq();
   result = FLASH_Erase(&s_flashDriver, addr, pflashSectorSize, kFTFx_ApiEraseKey);
   if (kStatus_FTFx_Success != result)
   {
      error_trap();
   }

   // Verify sector if it's been erased.
   result = FLASH_VerifyErase(&s_flashDriver, addr, pflashSectorSize, kFTFx_MarginValueUser);
   if (kStatus_FTFx_Success != result)
   {
      error_trap();
   }
   __enable_irq();
}

__RAMFUNC(RAM2) void FlashWriteMemory(uint32_t addr)

{

   __disable_irq();
      result = FLASH_Program(&s_flashDriver, addr, (uint8_t *)s_buffer, sizeof(s_buffer));
      if (kStatus_FTFx_Success != result){
         error_trap();
      }

      //Verify programming by Program Check command with user margin levels
      result = FLASH_VerifyProgram(&s_flashDriver, addr, sizeof(s_buffer), (const uint8_t *)s_buffer, kFTFx_MarginValueUser,&failAddr, &failDat);
      if (kStatus_FTFx_Success != result){
         error_trap();
      }

      // Post-preparation work about flash Cache/Prefetch/Speculation.
      FTFx_CACHE_ClearCachePrefetchSpeculation(&s_cacheDriver, false);

    __enable_irq();
}

Tell me please if this is the right way.

Thank you for help!

Have a nice day

Luca

0 Kudos
1,254 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Luca,

You place all Flash operation code to SRAM and execute Flash operation from SRAM, which should be correct.

While, I double check with the Kinetis L expert, the pflash demo should works at KL33 only to place flash launch command at SRAM. There is not necessary to place all Flash operation code at SRAM.

Sorry for I don't have KL33Z64 related board on hand, I couldn't do that test.


Have a great day,
Mike

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

1,254 Views
luca_securo
Contributor III

Hi Mike,

   

What do you mean with "the pflash demo should works at KL33 only to place flash launch command at SRAM" ?

I read the AN4695 another time and  I read about "FlashLaunchCommand" in section 6 but I don't understand very well what I have to do in my project. (there is no examples for MCUXpresso)

Thanks a lot!

Luca

0 Kudos
1,255 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Luca,

I use FRDM-KL43Z board with SDK provided [pflash] demo, when debug the code into ftfx_command_sequence() function code  in <fsl_ftfx_controller.c> file.

You will find below code and the callFtfxRunCommand call the code at RAM:

pastedImage_1.png

In previous reply, I mentioned the FTFx_DRIVER_IS_FLASH_RESIDENT macro definition will copy Flash run command function to RAM.

Below is the s_ftfxRunCommandFunctionCode[] assembly instruction, which function is same with below C code, you could found at AN4695:

pastedImage_2.png

When you debug the code, you could find the same data located at RAM address 0x1fffe0e0:

pastedImage_3.png

The ftfx_command_sequence() function will call these assembly instruction when run Flash command.

Wish it helps.


Have a great day,
Mike

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

1,254 Views
luca_securo
Contributor III

Hi Mark,

   it works!

Thank you for the support!

Luca

0 Kudos
1,254 Views
jorge_a_vazquez
NXP Employee
NXP Employee

Hi Luca

My colleague means that while you are attending to place some APIs from the SDK in RAM (FLASH_Program, FLASH_Erase, etc), there is no need to do this because this APIs already implement the RAM location inside of them.

If you check them you will find "flash_command_sequence" which will trigger the command in RAM.

You can find the example in the SDK package under driver_examples/pflash

Best regards

Jorge Alcala

0 Kudos
1,254 Views
mjbcswitzerland
Specialist V

Hi Luca

The KL33 is essentially the same as the KL43 with respect to the Flash operation. Can you confirm that your reference did work correctly on the KL43 board?

If you tell me which pins you have a UART connected to I can give you a KL33 binary that is build with the uTasker project in MCUXpresso (I just need to know which pins to connect) which allows you to verify Flash operations in its command line menu as shown in this video: https://youtu.be/Pe9A8qsefzQ (which generally works on all Kinetis parts)

See also
- http://www.utasker.com/kinetis/FRDM-KL43Z.html
- http://www.utasker.com/kinetis/TWR-KL43Z48M.html

Regards

Mark

0 Kudos