IAP远程更新系列文章目录如下:
1. IAP远程更新机制说明
STM32 操作内部Flash的函数接口
#include "inFlash.h"
#include "stm32f10x_flash.h"
/*!
* 功 能: 不检查的写入内部Flash
* param1: 起始地址
* param2: 要写入的数据指针
* param3: 要写入的数据的个数
* return: 无返回值
*/
void InFlashWriteNoCheck(uint32_t writeAddr, uint16_t *pBuffer, uint16_t numToWrite)
{
uint16_t i;
for(i=0; i<numToWrite; i++)
{
FLASH_ProgramHalfWord(writeAddr, pBuffer[i]); //在指定的地址写入半字
writeAddr += 2; //地址增加2.
}
}
/*!
* 功 能: 从指定地址开始写入指定长度的数据
* param1: 起始地址(此地址必须为2的倍数!!)
* param2: 要写入的数据指针
* param3: 半字(16位)数 (就是要写入的16位数据的个数.)
* return: 成功返回 0
* 失败返回 -1
*/
int InFlashWrite(uint32_t writeAddr, uint8_t *pBuffer, uint16_t numToWrite)
{
uint16_t i, temp = 0;
// 先判断地址是否合法
if(writeAddr<INFLASH_START_ADDR || (writeAddr>=(INFLASH_START_ADDR + INFLASH_TOTAL_SIZE * 1024)))
{
return -1;
}
FLASH_Unlock(); // 解锁
FLASH_SetLatency(FLASH_Latency_2); // 因为系统时钟为72M所以要设置两个时钟周期的延时
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR | FLASH_FLAG_EOP);
// 写入页之前要擦除整页,并判断是否擦除成功
while(FLASH_ErasePage(writeAddr) != FLASH_COMPLETE);
// 写入数据,小端存储,数据的高字节保存在高地址
if(numToWrite == 1)
{
temp |= pBuffer[0];
while(FLASH_ProgramHalfWord(writeAddr, temp) != FLASH_COMPLETE); //判断是否写入成功
}
else
{
for(i=0; i<numToWrite; i++) // 按照半字写入
{
temp = (pBuffer[2*i+1]<<8) | pBuffer[2*i]; //2个字节整合为1个半字
while(FLASH_ProgramHalfWord(writeAddr, temp) != FLASH_COMPLETE); //判断是否写入成功
writeAddr += 2; // 地址要加2,因为每次写入的是2个字节(1个半字)
}
}
FLASH_Lock(); // 上锁
return 0;
}
/*!
* 功 能: 读取指定地址的半字(16位数据)
* param1: 读地址(此地址必须为2的倍数!!)
* return: 读取到的数据
*/
uint16_t InFlashReadHalfWord(uint32_t faddr)
{
return *(uint16_t*)faddr;
}
/*!
* 功 能: 从指定地址开始读出指定长度的数据
* param1: 起始地址(此地址必须为2的倍数!!)
* param2: 要保存的缓冲区的地址
* param3: 要读取的半字(16位)数 (就是要读取的16位数据的个数.)
* return: 无返回值
*/
void InFlashRead(uint32_t readAddr, uint16_t *pBuffer, uint16_t numToRead)
{
uint16_t i;
for(i = 0; i < numToRead; i++)
{
pBuffer[i] = InFlashReadHalfWord(readAddr); //读取2个字节.
readAddr += 2; //偏移2个字节.
}
}
/*!
* 功 能: 测试函数,往内部Flash写入一个字节的数据
* param1: 起始地址
* param2: 要写入的数据
* return: 成功返回0
*/
int InFlashWriteChar(uint32_t writeAddr, uint8_t writeData)
{
return InFlashWrite(writeAddr, &writeData, 1); //写入一个字
}