得到要写入数据的页数和页内偏移地址,将该页起始到写入数据的首地址的数据读出
擦除该页
将要写入数据和之前的数据存入从新写入到该页
如果该页存不完数据,就增加页数,继续存储数据
FlashResult STMFLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
{
u16 i;
for(i = 0; i < NumToWrite; i++) {
if(FLASH_ProgramHalfWord(WriteAddr, pBufferi) != FLASH_COMPLETE) {
return FLASH_ERROR_PROGRAM_FAILED;
}
WriteAddr+=2;
}
return FLASH_SUCCESS;
}
FlashResult MyFlash_Write(u32 WriteAddr, u16 *pBuffer, u16 NumToWrite)
{
u32 offaddr; //去掉0X08000000后的地址(偏移地址)
u32 secpos; //扇区地址
u16 secoff; //扇区内偏移地址(16位字计算)
u16 secremain; //扇区内剩余地址(16位字计算)
u16 i;
FlashResult result;
if((WriteAddr < STM32_FLASH_BASE)||(WriteAddr >= (STM32_FLASH_BASE + 1024*STM32_FLASH_SIZE))) {
return FLASH_ERROR_INVALID_ADDR;
}
FLASH_Unlock(); // 解锁
offaddr = WriteAddr - STM32_FLASH_BASE;
secpos = offaddr/STM_SECTOR_SIZE;
secoff = (offaddr % STM_SECTOR_SIZE)/2;
secremain = STM_SECTOR_SIZE/2 - secoff;
if(NumToWrite <= secremain) secremain = NumToWrite;
while(1) {
result = MyFlash_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE, flashread_buffer.STMFLASH_BUF, STM_SECTOR_SIZE/2);
if(result != FLASH_SUCCESS) {
FLASH_Lock();
return result;
}
for(i = 0; i < secremain; i++) {
if(flashread_buffer.STMFLASH_BUFsecoff + i != 0xFFFF) break;
}
if(i < secremain) {
if(FLASH_ErasePage(secpos * STM_SECTOR_SIZE + STM32_FLASH_BASE) != FLASH_COMPLETE) {
FLASH_Lock();
return FLASH_ERROR_ERASE_FAILED;
}
for(i = 0; i < secremain; i++) {
flashread_buffer.STMFLASH_BUFi+secoff = pBufferi;
}
result = STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,flashread_buffer.STMFLASH_BUF, STM_SECTOR_SIZE/2);
if(result != FLASH_SUCCESS) {
FLASH_Lock();
return result;
}
} else {
result = STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间.
if(result != FLASH_SUCCESS) {
FLASH_Lock();
return result;
}
}
if(NumToWrite == secremain) break;
else {
secpos++;
secoff=0;
pBuffer += secremain;
WriteAddr+= secremain; //写地址偏移
NumToWrite -= secremain;
if(NumToWrite > (STM_SECTOR_SIZE/2)) secremain=STM_SECTOR_SIZE/2;//下一个扇区还是写不完
else secremain = NumToWrite;
}
}
FLASH_Lock();
return FLASH_SUCCESS;
}
向flash写入数据的流程为:
1、拿到偏移地址,和页地址,页内地址
2、解锁
3、从内存中读出数据
4、擦除该页
5、向该页写入数据(如果该页写不完就修改页地址,指向下一页)
6、上锁