这个是我们的,供参考,没有这种问题。
[C] 纯文本查看 复制代码 /*
*********************************************************************************************************
*
* 模块名称 : cpu内部falsh操作模块
* 文件名称 : bsp_cpu_flash.c
* 版 本 : V1.0
* 说 明 : 提供读写CPU内部Flash的函数
* 修改记录 :
* 版本号 日期 作者 说明
* V1.0 2013-02-01 armfly 正式发布
*
* Copyright (C), 2013-2014, 安富莱电子 [url]www.armfly.com[/url]
*
*********************************************************************************************************
*/
#include "bsp.h"
#define SECTOR_MASK 0xFFFFF800
/*
*********************************************************************************************************
* 函 数 名: bsp_GetSector
* 功能说明: 根据地址计算扇区首地址
* 形 参:无
* 返 回 值: 扇区首地址
*********************************************************************************************************
*/
uint32_t bsp_GetSector(uint32_t _ulWrAddr)
{
uint32_t sector = 0;
sector = _ulWrAddr & SECTOR_MASK;
return sector;
}
/*
*********************************************************************************************************
* 函 数 名: bsp_ReadCpuFlash
* 功能说明: 读取CPU Flash的内容
* 形 参:_ucpDst : 目标缓冲区
* _ulFlashAddr : 起始地址
* _ulSize : 数据大小(单位是字节)
* 返 回 值: 0=成功,1=失败
*********************************************************************************************************
*/
uint8_t bsp_ReadCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpDst, uint32_t _ulSize)
{
uint32_t i;
/* 如果偏移地址超过芯片容量,则不改写输出缓冲区 */
if (_ulFlashAddr + _ulSize > FLASH_BASE_ADDR + FLASH_SIZE)
{
return 1;
}
/* 长度为0时不继续操作,否则起始地址为奇地址会出错 */
if (_ulSize == 0)
{
return 1;
}
for (i = 0; i < _ulSize; i++)
{
*_ucpDst++ = *(uint8_t *)_ulFlashAddr++;
}
return 0;
}
/*
*********************************************************************************************************
* 函 数 名: bsp_CmpCpuFlash
* 功能说明: 比较Flash指定地址的数据.
* 形 参: _ulFlashAddr : Flash地址
* _ucpBuf : 数据缓冲区
* _ulSize : 数据大小(单位是字节)
* 返 回 值:
* FLASH_IS_EQU 0 Flash内容和待写入的数据相等,不需要擦除和写操作
* FLASH_REQ_WRITE 1 Flash不需要擦除,直接写
* FLASH_REQ_ERASE 2 Flash需要先擦除,再写
* FLASH_PARAM_ERR 3 函数参数错误
*********************************************************************************************************
*/
uint8_t bsp_CmpCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpBuf, uint32_t _ulSize)
{
uint32_t i;
uint8_t ucIsEqu; /* 相等标志 */
uint8_t ucByte;
/* 如果偏移地址超过芯片容量,则不改写输出缓冲区 */
if (_ulFlashAddr + _ulSize > FLASH_BASE_ADDR + FLASH_SIZE)
{
return FLASH_PARAM_ERR; /* 函数参数错误 */
}
/* 长度为0时返回正确 */
if (_ulSize == 0)
{
return FLASH_IS_EQU; /* Flash内容和待写入的数据相等 */
}
ucIsEqu = 1; /* 先假设所有字节和待写入的数据相等,如果遇到任何一个不相等,则设置为 0 */
for (i = 0; i < _ulSize; i++)
{
ucByte = *(uint8_t *)_ulFlashAddr;
if (ucByte != *_ucpBuf)
{
if (ucByte != 0xFF)
{
return FLASH_REQ_ERASE; /* 需要擦除后再写 */
}
else
{
ucIsEqu = 0; /* 不相等,需要写 */
}
}
_ulFlashAddr++;
_ucpBuf++;
}
if (ucIsEqu == 1)
{
return FLASH_IS_EQU; /* Flash内容和待写入的数据相等,不需要擦除和写操作 */
}
else
{
return FLASH_REQ_WRITE; /* Flash不需要擦除,直接写 */
}
}
/*
*********************************************************************************************************
* 函 数 名: bsp_WriteCpuFlash
* 功能说明: 写数据到CPU 内部Flash。
* 形 参: _ulFlashAddr : Flash地址
* _ucpSrc : 数据缓冲区
* _ulSize : 数据大小(单位是字节)
* 返 回 值: 0-成功,1-数据长度或地址溢出,2-写Flash出错(估计Flash寿命到)
*********************************************************************************************************
*/
uint8_t bsp_WriteCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpSrc, uint32_t _ulSize)
{
uint32_t i;
uint8_t ucRet;
uint16_t usTemp;
FLASH_Status status = FLASH_COMPLETE;
/* 如果偏移地址超过芯片容量,则不改写输出缓冲区 */
if (_ulFlashAddr + _ulSize > FLASH_BASE_ADDR + FLASH_SIZE)
{
return 1;
}
/* 长度为0 时不继续操作 */
if (_ulSize == 0)
{
return 0;
}
/* 长度为奇数时不继续操作 */
if ((_ulSize % 2) != 0)
{
return 1;
}
ucRet = bsp_CmpCpuFlash(_ulFlashAddr, _ucpSrc, _ulSize);
if (ucRet == FLASH_IS_EQU)
{
return 0;
}
__set_PRIMASK(1); /* 关中断 */
/* FLASH 解锁 */
FLASH_Unlock();
/* Clear pending flags (if any) */
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
/* 需要擦除 */
if (ucRet == FLASH_REQ_ERASE)
{
status = FLASH_ErasePage(bsp_GetSector(_ulFlashAddr));
if (status != FLASH_COMPLETE)
{
return 2;
}
}
/* 按字节模式编程(为提高效率,可以按字编程,一次写入4字节) */
for (i = 0; i < _ulSize / 2; i++)
{
//FLASH_ProgramByte(_ulFlashAddr++, *_ucpSrc++);
usTemp = _ucpSrc[2 * i];
usTemp |= (_ucpSrc[2 * i + 1] << 8);
status = FLASH_ProgramHalfWord(_ulFlashAddr, usTemp);
if (status != FLASH_COMPLETE)
{
break;
}
_ulFlashAddr += 2;
}
/* Flash 加锁,禁止写Flash控制寄存器 */
FLASH_Lock();
__set_PRIMASK(0); /* 开中断 */
if (status == FLASH_COMPLETE)
{
return 0;
}
return 2;
}
/***************************** 安富莱电子 [url]www.armfly.com[/url] (END OF FILE) *********************************/
[C] 纯文本查看 复制代码 /*
*********************************************************************************************************
*
* 模块名称 : cpu内部falsh操作模块
* 文件名称 : bsp_cpu_flash.h
* 版 本 : V1.0
*
* Copyright (C), 2013-2014, 安富莱电子 [url]www.armfly.com[/url]
*
*********************************************************************************************************
*/
#ifndef _BSP_CPU_FLASH_H_
#define _BSP_CPU_FLASH_H_
#define FLASH_BASE_ADDR 0x08000000 /* Flash基地址 */
#define FLASH_SIZE (1*1024*1024) /* Flash 容量 */
/* Base address of the Flash sectors */
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */
#define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbytes */
#define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbytes */
#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */
#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */
#define FLASH_IS_EQU 0 /* Flash内容和待写入的数据相等,不需要擦除和写操作 */
#define FLASH_REQ_WRITE 1 /* Flash不需要擦除,直接写 */
#define FLASH_REQ_ERASE 2 /* Flash需要先擦除,再写 */
#define FLASH_PARAM_ERR 3 /* 函数参数错误 */
uint8_t bsp_ReadCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpDst, uint32_t _ulSize);
uint8_t bsp_WriteCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpSrc, uint32_t _ulSize);
uint8_t bsp_CmpCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpBuf, uint32_t _ulSize);
#endif
/***************************** 安富莱电子 [url]www.armfly.com[/url] (END OF FILE) *********************************/
|