此封装对上层应用接口友好,支持任意长度数据,可从操作失败的地方再次操作(不用重新开始),是IAP必备之选! Flsh.h文件内容如下
- #ifndef __FLASH_H
- #define __FLASH_H
- /* Includes ------------------------------------------------------------------*/
- #include "STM32f10x.h"
- /* Define the STM32F10x FLASH Page Size depending on the used STM32 device */
- #if defined (STM32F10X_HD) || defined (STM32F10X_HD_VL) || defined (STM32F10X_CL) || defined (STM32F10X_XL)
- #define FLASH_PAGE_SIZE ((uint16_t)0x800)
- #else
- #define FLASH_PAGE_SIZE ((uint16_t)0x400)
- #endif
- /* Interface functions ---------------------------------------------------------*/
- void Flash_InitOperation(void);
- FLASH_Status Flash_WriteOperation(const void* pBuffer, uint16_t Length);
- void Flash_EndOperation(void);
- #endif
复制代码
Flsh.c文件内容如下
- #include "Flash.h"
- /* Private define ------------------------------------------------------------*/
- #define FLASH_WriteAddress ((uint32_t)0x08005000) //前20KB留给IAP,APP从0x08005000开始运行
- typedef enum {FAILED = 0, PASSED = !FAILED} STATUS;
- /* Private variables ---------------------------------------------------------*/
- uint16_t EraseCounter;
- uint32_t WriteAddress;
- uint16_t RemainSpace;
- /* Private functions ---------------------------------------------------------*/
- STATUS Flash_CompareOperation(const void* pBuffer, uint32_t Address, uint16_t Length);
- void Flash_InitOperation(void)
- {
- EraseCounter = 0;
- WriteAddress = FLASH_WriteAddress;
- RemainSpace = 0;
- FLASH_LockBank1();
-
- /* Unlock the Flash Bank1 Program Erase controller */
- FLASH_UnlockBank1();
- /* Clear All pending flags */
- FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
- }
- FLASH_Status Flash_WriteOperation(const void* pBuffer, uint16_t Length)
- {
- FLASH_Status FLASHStatus = FLASH_COMPLETE;
- uint16_t i, j, off;
- uint16_t NbrOfPage = 0;
- uint16_t* p16 = NULL;
- uint32_t* p32 = NULL;
- uint8_t* p8 = NULL;
- if(Length > RemainSpace)
- {
- NbrOfPage = (Length-RemainSpace)/FLASH_PAGE_SIZE + 1;
- }
-
- for(j = 0; (j < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); j++, EraseCounter++)
- {
- FLASHStatus = FLASH_ErasePage(FLASH_WriteAddress + (FLASH_PAGE_SIZE * EraseCounter));
- }
-
- i = 0;
- off = 0;
- p32 = (uint32_t*)pBuffer;
- while((i*4 < Length-3) && (FLASHStatus == FLASH_COMPLETE))
- {
- FLASHStatus = FLASH_ProgramWord(WriteAddress, p32[i++]);
- WriteAddress += 4;
- }
-
- off = i*4;
- p16 = (uint16_t*)pBuffer;
- if((off+1 < Length) && (FLASHStatus == FLASH_COMPLETE))
- {
- FLASHStatus = FLASH_ProgramHalfWord(WriteAddress, p16[i*2]);
- WriteAddress += 2;
- off += 2;
- }
-
- p8 = (uint8_t*)pBuffer;
- if((off < Length) && (FLASHStatus == FLASH_COMPLETE))
- {
- FLASHStatus = FLASH_ProgramOptionByteData(WriteAddress, p8[off]);
- WriteAddress += 1;
- }
- FLASH_LockBank1(); //如果不关闭,Flash读操作有可能会擦除Flash - 2014.06.24
-
- if( PASSED == Flash_CompareOperation(pBuffer, WriteAddress-Length, Length) )
- {
- RemainSpace += FLASH_PAGE_SIZE*j - Length;
- }
- else
- {
- WriteAddress -= Length;
- EraseCounter -= j;
- FLASH_ErasePage(WriteAddress);
- FLASHStatus = FLASH_ERROR_PG;
- }
- FLASH_UnlockBank1();
-
- return FLASHStatus;
- }
- STATUS Flash_CompareOperation(const void* pBuffer, uint32_t Address, uint16_t Length)
- {
- STATUS MemoryProgramStatus = PASSED;
- uint16_t i, off;
- uint16_t* p16 = NULL;
- uint32_t* p32 = NULL;
- uint8_t* p8 = NULL;
-
- i = 0;
- off = 0;
- p32 = (uint32_t*)pBuffer;
- while((i*4 < Length-3) && (MemoryProgramStatus != FAILED))
- {
- if((*(__IO uint32_t*) Address) != p32[i++])
- {
- MemoryProgramStatus = FAILED;
- }
- Address += 4;
- }
-
- off = i*4;
- p16 = (uint16_t*)pBuffer;
- if((off+1 < Length) && (MemoryProgramStatus != FAILED))
- {
- if((*(__IO uint32_t*) Address) != p16[i*2])
- {
- MemoryProgramStatus = FAILED;
- }
- Address += 2;
- off += 2;
- }
-
- p8 = (uint8_t*)pBuffer;
- if((off < Length) && (MemoryProgramStatus != FAILED))
- {
- if((*(__IO uint32_t*) Address) != p8[off])
- {
- MemoryProgramStatus = FAILED;
- }
- }
-
- return MemoryProgramStatus;
- }
- void Flash_EndOperation(void)
- {
- FLASH_LockBank1();
- }
复制代码
推荐将要写入的数据分割成数段,当一段写入成功后再写入下一段,如果失败可反复写这一段直到成功。
1
|
|
|
|