【stm32f407】Flash programming

Publisher:那是一条路都Latest update time:2019-01-31 Source: eefocusKeywords:stm32f407 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Introduction to Flash

Different models of STM32F40xx/41xx have different FLASH capacities, the smallest is only 128K bytes, and the largest is 1024K bytes. The FLASH capacity of STM32F4 is 1024K bytes, as shown in the reference manual:


The flash memory module of STM32F4 consists of four parts: main memory, system memory, OPT area and option bytes. The main memory is used to store code and data constants (such as const type data). It is divided into 12 sectors, the first 4 sectors are 16KB in size, then sector 4 is 64KB in size, and sectors 5~11 are 128K in size. STM32F4 with different capacities has different number of sectors. For example, our STM32F407ZGT6 has all 12 sectors. From the above figure, it can be seen that the starting address of the main memory is 0X08000000. When B0 and B1 are connected to GND, the code starts running from 0X08000000.


System memory is mainly used to store the bootloader code of STM32F4. This code is fixed in STM32F4 when it leaves the factory, and is used to download code to the main memory. When B0 is connected to V3.3 and B1 is connected to GND, it starts from this memory (that is, enters the serial port download mode).


The OTP area, i.e. the one-time programmable area, is 528 bytes in total and is divided into two parts. The first 512 bytes (32 bytes per block, divided into 16 blocks) can be used to store some user data (one-time, written once, can never be erased!!), and the last 16 bytes are used to lock the corresponding block.


Option bytes to configure read protection, BOR level, software/hardware watchdog, and reset when the device is in Standby or Stop mode.


The flash memory interface register is used to control flash memory reading and writing, etc. It is the control mechanism of the entire flash memory module.


When performing a flash write operation, any read operation on the flash memory will lock the bus, and the read operation can only be performed correctly after the write operation is completed; that is, when performing a write or erase operation, code or data read operations cannot be performed.


1. Flash memory reading

STM32F4 can access the built-in flash memory module through the internal I-Code command bus or D-Code data bus. In this chapter, we mainly explain data reading and writing, that is, accessing the internal flash memory module through the D-Code data bus. In order to accurately read the Flash data, the number of waiting cycles (LATENCY) must be correctly set in the Flash access control register (FLASH_ACR) according to the CPU clock (HCLK) frequency and the device power supply voltage. When the power supply voltage is lower than 2.1V, the prefetch buffer must be turned off. The corresponding relationship between the Flash waiting cycle and the CPU clock frequency is shown in the table:


The waiting cycle is set by the three bits LATENCY[2:0] of the FLASH_ACR register. After the system is reset, the CPU clock frequency is the internal 16M RC oscillator, and the default LATENCY is 0, which is 1 waiting cycle. The power supply voltage is generally 3.3V, so before we set the 168Mhz frequency as the CPU clock, we must first set LATENCY to 5, otherwise the FLASH reading and writing may fail, causing a crash. During normal operation (168Mhz), although FLASH requires 6 CPU waiting cycles, because the STM32F4 has an adaptive real-time memory accelerator (ARTAccelerator), it pre-fetches instructions through the instruction cache memory to achieve an operating speed equivalent to 0 FLASH waiting.


STM23F4 FLASH reading is very simple. For example, we want to read a word (word) from address addr.


8 bits for a section, 16 bits for a halfword, and 32 bits for a word), which can be read using the following statement:


data=*(vu32*)addr;


Force addr to be converted into a vu32 pointer, and then take the value of the address pointed to by the pointer to get the value of the addr address.


Similarly, changing the above vu32 to vu16 can read a half word of the specified address.


2. Programming and erasing flash memory

The CPU clock frequency (HCLK) must not be lower than 1 MHz when performing any Flash programming operation (erase or program). If a device reset occurs during a Flash operation, the contents of the Flash are not guaranteed.


During a write or erase operation on the STM32F4's Flash, any attempt to read the Flash will cause the bus to be blocked. The read operation can only be processed correctly after the programming operation is completed. This means that code or data acquisition operations cannot be performed from the Flash during the write/erase operation.


The flash programming of STM32F4 is controlled by 6 32-bit registers, which are:


FLASH Access Control Register (FLASH_ACR)


FLASH Key Register (FLASH_KEYR)


FLASH Option Key Register (FLASH_OPTKEYR)


FLASH Status Register (FLASH_SR)


FLASH Control Register (FLASH_CR)


FLASH Option Control Register (FLASH_OPTCR)


After STM32F4 is reset, the FLASH programming operation is protected and the FLASH_CR register cannot be written. The write protection can be removed by writing a specific sequence (0X45670123 and 0XCDEF89AB) to the FLASH_KEYR register. Only after the write protection is removed can we operate the relevant registers.


The unlock sequence of FLASH_CR is:


1) Write 0X45670123 to FLASH_KEYR


2) Write 0XCDEF89AB to FLASH_KEYR


Through these two steps, FLASH_CR can be unlocked. If a write error occurs, FLASH_CR will be locked and can only be unlocked again after the next reset.


The number of programming bits of the STM32F4 flash memory can be configured by the PSIZE field of FLASH_CR. The setting of PSIZE must match the power supply voltage, as shown in the figure:

Since the voltage of our development board is 3.3V, PSIZE must be set to 10, that is, 32-bit parallel bits. Erasing or programming must be based on 32 bits. When programming the FLASH of STM32F4, it must also be required that the FLASH of the write address must be erased (that is, its value must be 0XFFFFFFFF), otherwise it cannot be written. The standard programming steps of STM32F4 are as follows:


1) Check the BSY bit in FLASH_SR to ensure that no FLASH operation is currently being performed.


2) Set the PG bit in the FLASH_CR register to 1 to activate FLASH programming.


3) Perform data write operation for the desired memory address (in the main memory block or OTP area):


—Write by byte when the number of parallel bits is x8 (PSIZE=00)


—When the number of parallel bits is x16, write as half word (PSIZE=01)


—Write by word when the number of parallel bits is x32 (PSIZE=02)


—Write as double word when the number of parallel bits is x64 (PSIZE=03)


4) Wait for the BSY bit to be cleared to complete a programming.


Follow the above four steps to complete a FLASH programming. However, there are a few points to note: 1. Before programming, make sure


The FLASH to be written has been erased. 2. Unlock first (otherwise FLASH_CR cannot be operated). 3. The programming operation is


The OPT area is also valid and the method is exactly the same.


When we program the FLASH of STM32F4, we must first determine whether the abbreviated address has been erased, so we have


It is necessary to introduce the flash memory erasure of STM32F4. There are two types of flash memory erasure of STM32F4: sector erase and whole chip erase.


The steps to erase a sector are as follows:


1) Check whether the LOCK of FLASH_CR is unlocked. If not, unlock it first.


2) Check the BSY bit in the FLASH_SR register to ensure that no FLASH operation is currently being performed.


3) In the FLASH_CR register, set the SER bit to 1 and select the sector to be erased from the 12 sectors of the main memory block.


Sector (SNB)


4) Set the STRT bit in the FLASH_CR register to 1 to trigger the erase operation.


5) Wait for BSY bit to clear


After the above five steps, you can erase a sector.


Through the above understanding, we basically know the steps to be performed for reading and writing STM32F4 flash memory. Next, I


Let's take a look at the register descriptions related to reading and writing.


The first one to be introduced is the FLASH access control register: FLASH_ACR. The description of each bit of this register is shown in the figure:

Here, we focus on the three bits LATENCY[2:0]. These three bits must be based on the operating voltage of our MCU.


and frequency to make the correct settings, otherwise, the system may freeze. For setting rules, see Table 39.1.1.


The three bits PRFTEN are also very important. In order to achieve the best performance, we generally set these three bits to 1.


The second one to be introduced is the FLASH key register: FLASH_KEYR. The description of each bit of this register is shown in the figure:


This register is mainly used to unlock FLASH_CR. A specific sequence (KEY1 and KEY2) must be written to this register.


After unlocking, the FLASH_CR register can be written.


The third one to be introduced is the FLASH control register: FLASH_CR. The description of each bit of this register is shown in the figure:


In this chapter, we only use the LOCK, STRT, PSIZE[1:0], SNB[3:0], SER and PG bits of this register.


LOCK bit, which is used to indicate whether the FLASH_CR register is locked. After detecting the correct unlock sequence,


Hardware clears it to 0. After an unsuccessful unlock operation, this bit will not change until the next system reset.


STRT bit, this bit is used to start an erase operation. Writing 1 to this bit will execute an erase operation.


The PSIZE[1:0] bit is used to set the programming width. At 3.3V, we just need to set PSIZE=2.


SNB[3:0] bits, these 4 bits are used to select the sector number to be erased, and the value range is 0~11.


SER bit, this bit is used to select the sector erase operation. When erasing a sector, this bit needs to be set to 1.


PG bit, this bit is used to select the programming operation. When writing data to FLASH, this bit needs to be set to 1.


We will not introduce the other bits of FLASH_CR here.


The last thing to introduce is the FLASH status register: FLASH_SR. The description of each bit of this register is shown in the figure:


We mainly use the BSY bit of this register. When this bit is 1, it indicates that the FLASH operation is being performed.


When 0, it means that no FLASH operation is currently being performed.


2. Stm32 flash operation steps

Stm32 official library functions are distributed in the files stm32f4xx_flash.c and stm32f4xx_flash.h


1) Lock and unlock functions


As explained above, the FLASH must be unlocked before writing. The unlocking operation means that a specific sequence (KEY1 and KEY2) must be written to the FLASH_KEYR register. The firmware library function is very simple to implement:


void FLASH_Unlock(void);


In the same way, after the FLASH write operation is completed, we need to lock the FLASH. The library function used is:


void FLASH_Lock(void);


2) Write operation function


The firmware library provides four FLASH write functions:


FLASH_StatusFLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data);


FLASH_StatusFLASH_ProgramWord(uint32_t Address, uint32_t Data);


FLASH_StatusFLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);


FLASH_StatusFLASH_ProgramByte(uint32_t Address, uint8_t Data);


The meaning of these functions is relatively easy to understand from their names. They are functions for writing double words, words, half words, and bytes respectively.


3) Erase function


The firmware library provides four FLASH erase functions:


FLASH_StatusFLASH_EraseSector(uint32_t FLASH_Sector, uint8_t VoltageRange);


FLASH_StatusFLASH_EraseAllSectors(uint8_t VoltageRange);


FLASH_StatusFLASH_EraseAllBank1Sectors(uint8_t VoltageRange);


FLASH_StatusFLASH_EraseAllBank2Sectors(uint8_t VoltageRange);


The first two functions are relatively easy to understand. One is used to erase a certain sector, and the other is used to erase all sectors.


The third and fourth functions are mainly for STM32F42X series and STM32F43X series chips, because they divide all sectors into two banks. So these two functions are used to erase sectors under two banks. The value range of the first parameter has been defined in the firmware library with related macro definition identifiers, which are FLASH_Sector_0~FLASH_Sector_11 (for the STM32F407 we use, the maximum is


FLASH_Sector_11), for the second parameter of these functions, the power supply voltage range here is 3.3V, so just select VoltageRange_3.


4) Get FLASH status


The main function called to obtain the FLASH status is:


FLASH_StatusFLASH_GetStatus(void);


The return value is defined by an enumeration type:


typedefenum


{


FLASH_BUSY = 1, // Operation busy


FLASH_ERROR_RD, //Read protection error


FLASH_ERROR_PGS, //Programming sequence error


FLASH_ERROR_PGP, //Parallel programming bit error


FLASH_ERROR_PGA, //Programming alignment error


FLASH_ERROR_WRP, //Write protection error


FLASH_ERROR_PROGRAM, //Programming error


FLASH_ERROR_OPERATION, // Operation error


FLASH_COMPLETE//Operation completed


}FLASH_Status;


From here we can see several states of FLASH operation.


5) Waiting for the operation to complete


When performing a flash write operation, any read operation on the flash memory will lock the bus, and the read operation can only be performed correctly after the write operation is completed; that is, when performing a write or erase operation, code or data read operations cannot be performed.


So before each operation, we have to wait for the last operation to complete before starting this operation. The function used is: FLASH_Status FLASH_WaitForLastOperation(void)


The return value is the status of FLASH, which is easy to understand. We don’t use this function much in the firmware library, but we can see it many times in the firmware library function body.


6) Read FLASH specific address data function


If there is writing, there must be reading. However, the firmware library does not provide a function to read the data at the specified address of FLASH. Here we provide a function to read one word at a time from the specified address:


u32STMFLASH_ReadWord(u32 faddr)


{


return *(vu32*)faddr;


}


7) Write option byte operation


The firmware library also provides a series of option byte area operation functions. Since this experiment does not use option byte area operations, we will not explain them in detail here.


3. Operation flash source code

Flash.h


#ifndef_FLASH_H_H_H

#define_FLASH_H_H_H

#include "stm32f4xx_gpio.h"

#include "stm32f4xx_rcc.h"

#include "stm32f4xx_flash.h"

 

//FLASH start address

#defineSTM32_FLASH_BASE 0x08000000 //The starting address of STM32FLASH

 

//The starting address of the FLASH sector

#defineADDR_FLASH_SECTOR_0 ((u32)0x08000000) //Sector 0 starting address, 16Kbytes  

#defineADDR_FLASH_SECTOR_1 ((u32)0x08004000) //Sector 1 starting address, 16Kbytes  

#defineADDR_FLASH_SECTOR_2 ((u32)0x08008000) //Sector 2 starting address, 16Kbytes  

#defineADDR_FLASH_SECTOR_3 ((u32)0x0800C000) //Sector 3 starting address, 16Kbytes  

#defineADDR_FLASH_SECTOR_4 ((u32)0x08010000) //Sector 4 starting address, 64Kbytes  

#defineADDR_FLASH_SECTOR_5 ((u32)0x08020000) //Sector 5 starting address, 128Kbytes  

#defineADDR_FLASH_SECTOR_6 ((u32)0x08040000) //Sector 6 starting address, 128Kbytes  

#defineADDR_FLASH_SECTOR_7 ((u32)0x08060000) //Sector 7 starting address, 128 Kbytes  

#defineADDR_FLASH_SECTOR_8 ((u32)0x08080000) //Sector 8 starting address, 128Kbytes  

#defineADDR_FLASH_SECTOR_9 ((u32)0x080A0000) //Sector 9 starting address, 128Kbytes  

#defineADDR_FLASH_SECTOR_10 ((u32)0x080C0000) //Sector 10 starting address, 128Kbytes  

#defineADDR_FLASH_SECTOR_11 ((u32)0x080E0000) //Sector 11 starting address, 128Kbytes  

 

u32STMFLASH_ReadWord(u32 faddr); //Read word  

voidSTMFLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite); //Write data of specified length starting from the specified address

voidSTMFLASH_Read(u32 ReadAddr,u32 *pBuffer,u32 NumToRead); //Read data of specified length starting from the specified address

#endif


Flash.c


#include "flash.h"

//Read the half word (16-bit data) of the specified address 

//faddr: read address

//Return value: corresponding data.

u32STMFLASH_ReadWord(u32 faddr)

{

  return *(vu32*)faddr; 

}  

//Get the flash sector where a certain address is located

//addr: flash address

//Return value: 0~11, that is, the sector where addr is located

uint16_tSTMFLASH_GetFlashSector(u32 addr)

{

  if(addr

  else if(addr

  else if(addr

  else if(addr

  else if(addr

  else if(addr

  else if(addr

  else if(addr

  else if(addr

  else if(addr

  else if(addr

  return FLASH_Sector_11;    

}

//Write data of specified length starting from the specified address

//Special note: Because the sectors of STM32F4 are too large to store sector data locally, this function

// If the write address is not 0XFF, the entire sector will be erased first and the sector data will not be saved.

// Writing to an address other than 0XFF will cause the entire sector data to be lost. It is recommended to ensure that the sector

// If there is no important data, it is best to erase the entire sector first, and then write slowly. 

//This function is also valid for the OTP area! It can be used to write the OTP area!

//OTP area address range: 0X1FFF7800~0X1FFF7A0F

//WriteAddr: starting address (this address must be a multiple of 4!!)

//pBuffer: data pointer

//NumToWrite: Number of words (32 bits) (that is, the number of 32-bit data to be written.) 

voidSTMFLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite)          

  FLASH_Status status = FLASH_COMPLETE;

  u32 addrx=0;

  u32 endaddr=0;   

 if(WriteAddr

  FLASH_Unlock(); //Unlock

  FLASH_DataCacheCmd(DISABLE); //Data cache must be disabled during FLASH erase

                 

  addrx=WriteAddr; //Starting address to write

  endaddr=WriteAddr+NumToWrite*4; //End address of writing

  if(addrx<0X1FFF0000) //Only the main storage area needs to perform the erase operation!!

  {

    while(addrx

    {

     if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//There is a non-0XFFFFFFFF place, to erase this sector

      {  

       status=FLASH_EraseSector(STMFLASH_GetFlashSector(addrx),VoltageRange_3);//VCC=between 2.7~3.6V!!

        if(status!=FLASH_COMPLETE)break; //An error occurred

      }else addrx+=4;

    } 

  }

  

  if(status==FLASH_COMPLETE)

  {

    while(WriteAddr

    {

     if(FLASH_ProgramWord(WriteAddr,*pBuffer)!=FLASH_COMPLETE)//write data

      { 

        break; //Write exception

      }

      WriteAddr+=4;

      pBuffer++;

    } 

  }

  FLASH_DataCacheCmd(ENABLE); //FLASH erasing is complete, data cache is enabled

  FLASH_Lock(); //Lock

 

//Read data of specified length starting from the specified address

//ReadAddr: starting address

//pBuffer: data pointer

//NumToRead: number of words (4 bits)

voidSTMFLASH_Read(u32 ReadAddr,u32 *pBuffer,u32 NumToRead)         

{

  u32 i;

  for(i=0;i

  {

    pBuffer[i]=STMFLASH_ReadWord(ReadAddr); //Read 4 bytes.

    ReadAddr+=4; //Offset 4 bytes.      

  }

}


Main.c


#include "led.h"

#include "key.h"

#include "delay.h"

#include "uart.h"

#include "exit.h"

#include "iwdog.h"

#include "pwm.h"

#include "can.h"

#include "flash.h"

 

intcheckSystem( )

{

  union check

  {

    int i;

    char ch;

  }c;

  ci = 1;

  return (c.ch == 1);

}

//String array to be written to STM32FLASH

const u8TEXT_Buffer[]={"http://blog.csdn.net/xiaoxiaopengbo"};

#defineTEXT_LENTH sizeof(TEXT_Buffer) //array length      

#defineSIZE TEXT_LENTH/4+((TEXT_LENTH%4)?1:0)

 

#defineFLASH_SAVE_ADDR 0X0800C004 //Set the FLASH save address (must be an even number, and the sector it is in must be larger than the sector occupied by this code.

                                                                                             //Otherwise, the entire sector may be erased during the write operation, causing part of the program to be lost and causing a crash.

intmain(void)

{

  u8 datatemp[SIZE];      

  u8 check_platform = checkSystem();

  

  

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //Set system interrupt priority group 2

  My_USART2_Init();

  delay_init(168); //Initialize delay function

  

  if(check_platform == 1)

  {

    printf("small endian\r\n");

  }

  else

  {

    printf("big endian\r\n");

  }

 STMFLASH_Write(FLASH_SAVE_ADDR,(u32*)TEXT_Buffer,SIZE);

  printf("flahs write success\r\n");

  

  delay_ms(2000);

 STMFLASH_Read(FLASH_SAVE_ADDR,(u32*)datatemp,SIZE);

  printf("flash read:%s\r\n",datatemp);

   

}


This function is mainly used to write TEXT_Buffer to flash and then read it out after 2 seconds.


The execution results are as follows:


When debugging, the memory is found to be:

It was found to be little-endian mode, so a mode check was added


I checked online and found that ARM can switch between big and small endian modes. Some people say that stm32 can also switch, but at least I didn't find it in the data sheet, and the default is little endian, so I won't pay attention to it for now. If you know, please add some information.

Keywords:stm32f407 Reference address:【stm32f407】Flash programming

Previous article:【stm32f407】Memory management based on SRAM
Next article:【stm32f407】CAN bus

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号