Arm Community
Arm Community
  • Site
  • User
  • Site
  • Search
  • User
  • Groups
    • Research Collaboration and Enablement
    • DesignStart
    • Education Hub
    • Innovation
    • Open Source Software and Platforms
  • Forums
    • AI and ML forum
    • Architectures and Processors forum
    • Arm Development Platforms forum
    • Arm Development Studio forum
    • Arm Virtual Hardware forum
    • Automotive forum
    • Compilers and Libraries forum
    • Graphics, Gaming, and VR forum
    • High Performance Computing (HPC) forum
    • Infrastructure Solutions forum
    • Internet of Things (IoT) forum
    • Keil forum
    • Morello Forum
    • Operating Systems forum
    • SoC Design and Simulation forum
    • 中文社区论区
  • Blogs
    • AI and ML blog
    • Announcements
    • Architectures and Processors blog
    • Automotive blog
    • Graphics, Gaming, and VR blog
    • High Performance Computing (HPC) blog
    • Infrastructure Solutions blog
    • Innovation blog
    • Internet of Things (IoT) blog
    • Operating Systems blog
    • Research Articles
    • SoC Design and Simulation blog
    • Tools, Software and IDEs blog
    • 中文社区博客
  • Support
    • Arm Support Services
    • Documentation
    • Downloads
    • Training
    • Arm Approved program
    • Arm Design Reviews
  • Community Help
  • More
  • Cancel
Arm Community blogs
Arm Community blogs
Embedded blog Writing Data To Flash During Program Execution With The Freescale KL25z Series.
  • Blogs
  • Mentions
  • Sub-Groups
  • Tags
  • Jump...
  • Cancel
More blogs in Arm Community blogs
  • AI and ML blog

  • Announcements

  • Architectures and Processors blog

  • Automotive blog

  • Embedded blog

  • Graphics, Gaming, and VR blog

  • High Performance Computing (HPC) blog

  • Infrastructure Solutions blog

  • Internet of Things (IoT) blog

  • Operating Systems blog

  • SoC Design and Simulation blog

  • Tools, Software and IDEs blog

Tags
  • Flash Technology
Actions
  • RSS
  • More
  • Cancel
Related blog posts
Related forum threads

Writing Data To Flash During Program Execution With The Freescale KL25z Series.

Elliott Smith
Elliott Smith
December 2, 2013

This article explains how we wrote data to flash during program execution when developing the batteryless energy harvesting remote control. This remote control used an MCU from the Freescale KL25z series. The MkL25Z128VLK4 was used. Please be aware that, if done incorrectly, this can kill your MCU.

Defining a region in memory to store the data

The starting point for flashing data is to define a memory region to store the data in. At this point it is necessary to look at the memory map for the device to see where the flash is located and if there are any protected/reserved regions in it. If we look at the Freescale MkL25z series reference manual we can see that the regions specified in the example code below are suitable to store the data.

/*------------------------------------------------------------------------------
  Data stores for eink frame buffer and IR codes. 
    Volatile to prevent compiler optimisation
 *------------------------------------------------------------------------------*/
volatile ir_command device_1[45] __attribute__((at(0x09000)));
volatile ir_command device_2[45] __attribute__((at(0x0A000)));
volatile ir_command device_3[45] __attribute__((at(0x0B000)));
volatile ir_command device_4[45] __attribute__((at(0x0C000)));
volatile char frame_buff_store[176][33] __attribute__((at(0x0D000)));
volatile int page __attribute__((at(0x0C500)));
volatile int device __attribute__((at(0x0C504)));
volatile int signed tv_locat[6] __attribute__((at(0x0C800)));
volatile int signed dvd_locat[6] __attribute__((at(0x0CF00)));


These regions have been defined as global variables. The regions usually have to be long word aligned.

In the energy harvesting remote control example we defined regions for the infra-red commands that the remote control could “learn”. We also defined regions for the frame buffer, for the page and for the device so that the e-ink display could be altered accordingly. We added regions for the Television and the DVD player locations, these used accelerometer and magnetometer values to determine where the remote was pointing. If pointing at the television, the device would automatically switch to the Television User Interface.

Using Memory View in Keil Debugger

The next stage of the process is to test whether it is safe to flash the regions chosen. Memory View in Keil Debugger is excellent for this. Look at the 1 KB after the region defined for the data. This region should be blank and unchanging. If it is not it may be necessary to look at the scatter file to see what is next to it.

Once you are happy that you are not going to corrupt something by erasing the block of flash, it is time to erase the flash. For a successful erase to occur, and to ensure that the core does not lockup and reset, it is essential that nothing else is going to use the flash during these operations.

Erasing the block of Flash

This is achieved by placing the code to execute the flash commands into the on-board RAM for execution. To do this you need to right-hand click on the file you are using to write data to flash, and selecting options.  You then need to look at the memory assignment section at the bottom of the page and change the ‘Code / Const’ to a RAM region on your MCU. This will ensure that every time your application starts this section of code is copied into the RAM for execution.

The important registers for the MkL25Z series are the FCCOB registers and, as can be seen in the reference manual, these are numbered 0-B. The FSTAT register is needed to determine if the FCCOB registers are free to use.

/*------------------------------------------------------------------------------
  Erase the flash block containing the sector
 *------------------------------------------------------------------------------*/
int flash_EraseSector(long int sector)
{
    int temp1,temp2,temp3;

    //Dividing the sector address into the 3 bytes before starting to fill the FCCOB
  //registers reduces the risk of the operation being corrupted:

            temp1 = (sector << 8);
            temp1 = temp1 >> 24;
    
            temp2 = (sector << 16);
            temp2 = temp2 >> 24;
    
            temp3 = (sector << 24);
            temp3 = temp3 >> 24;
    
    //Wait until the command complete instruction is cleared indicate the FCCOB registers
  //are available:

            while(((FTFA->FSTAT)&(1UL << 7))==0x00);
    
    //Clear any previous errors from the last operation:
    
            if(!((FTFA->FSTAT)==0x80))
                    {FTFA->FSTAT = 0x30;}

            FTFA->FCCOB0 = 0x09;     // 0x09 is the instruction code for erase
            FTFA->FCCOB1 = temp1;    // Load the segment address into registers
            FTFA->FCCOB2 = temp2;
            FTFA->FCCOB3 = temp3;

            FTFA->FSTAT = 0x80;         // Writing a 1 to bit 7 of the FSTAT register launches 

            // Wait for command completion:

            while(((FTFA->FSTAT)&(1UL << 7))==0x00);

    return 1;

}


The example code above shows exactly how we did the erase for the MkL25Z series. This function is called from another handler function also running directly from RAM to reduce the risk of core lockup. The handler function is shown below. A delay is required between calling the handler function and carrying out flash commands to prevent core lockup. In the example code below this was achieved with a simple for loop.

/*------------------------------------------------------------------------------
  Write a page and device to flash memory.
 *------------------------------------------------------------------------------*/
void flash_memory_tv_loc(signed int ax,signed int ay,signed int az,signed int hx,signed int hy,signed int hz)
{
    int j;
    for(j=0;j<10000;j++); //delay
    flash_EraseSector((int)&tv_locat);
    for(j=0;j<100;j++);
    flash_writeLongWord((int)&tv_locat[0],ax);
    flash_writeLongWord((int)&tv_locat[1],ay);
    flash_writeLongWord((int)&tv_locat[2],az);
    flash_writeLongWord((int)&tv_locat[3],hx);
    flash_writeLongWord((int)&tv_locat[4],hy);
    flash_writeLongWord((int)&tv_locat[5],hz);

}


Writing data to Flash

The final part of writing data to flash is the write itself. This is very similar to erasing but with a different instruction code. The example code shows how this is achieved for the MkL25Z series.

/*------------------------------------------------------------------------------
  Write a long word to an erased flash block
 *------------------------------------------------------------------------------*/
int flash_writeLongWord(long int locat,long int value)
{
        int temp1,temp2,temp3,temp4,temp5,temp6,temp7;

            temp1 = (locat << 8);
            temp1 = temp1 >> 24;
            temp2 = (locat << 16);
            temp2 = temp2 >> 24;
            temp3 = (locat << 24);
            temp3 = temp3 >> 24;
            temp4 = value >> 24;
            temp5 = (value << 8);
            temp5 = temp5 >> 24;
            temp6 = (value << 16);
            temp6 = temp6 >> 24;
            temp7 = (value << 24);
            temp7 = temp7 >> 24;


            while(((FTFA->FSTAT)&(1UL << 7))==0x00);    

            if(!((FTFA->FSTAT)==0x80))
                    {FTFA->FSTAT = 0x30;}

            FTFA->FCCOB0 = 0x06;    //0x06 is instruction code for write long word.

            FTFA->FCCOB1 = temp1;
            FTFA->FCCOB2 = temp2;
            FTFA->FCCOB3 = temp3;
            FTFA->FCCOB4 = temp4;
            FTFA->FCCOB5 = temp5;
            FTFA->FCCOB6 = temp6;
            FTFA->FCCOB7 = temp7;

            FTFA->FSTAT = 0x80;

            while(((FTFA->FSTAT)&(1UL << 7))==0x00);

        return 1;
}


As can be seen, more of the FCCOB registers are required, when compared with an erase, because the location and the value must be specified.The instruction code for writing a long word is 0x06. The instruction code for an erase is 0x09. These can be looked up in the reference manual.

If you have problems with core lockup, check all the pointers for the functions/data you’re using to make sure they’re in RAM.

The next development step is available in the blog below.

Read next development step on infra-red code learning and repeating

Anonymous
  • emanuele.marraccini
    Offline emanuele.marraccini over 6 years ago

    Dear All,

    In the above article I read that "A delay is required between calling the handler function and carrying out flash commands to prevent core lockup."

    Caould You better explain what is the cause of the core lockup when no delay is added?

    I'm working with Kinetis  MK66FN2M0VMD18 on a custom board, could You confirm that this workaround is needed also for my target?

    Could You estimate the value of the delay to add before the Erase Sector Command and before Write Long Word Command?

    Thanks for Your support.

    Best Regards

    Emanuele

    • Cancel
    • Up 0 Down
    • Reply
    • More
    • Cancel
Embedded blog
  • The flexible approach to adding Functional Safety to a CPU

    James Scobie
    James Scobie
    Find out more about Functional Safety with SoC designs and Software Test Libraries.
    • November 8, 2022
  • The importance of building functional safety into your design right from the start

    Madhusudan Rao
    Madhusudan Rao
    Currently, there are many processors that are not designed with functional safety standards in mind and the use of these can lead to lengthy and costly qualification processes for safety relevant applications…
    • November 8, 2022
  • Arm Safety Ready program: Building confidence into your application

    Madhusudan Rao
    Madhusudan Rao
    To demonstrate Arm’s commitment to functional safety, we announce the launch of our Safety Ready program.
    • November 8, 2022