標籤:des style color strong 資料 art
因為要用內部FLASH代替外部EEPROM,把參數放在STM32的0x08000000+320K處,其中20K是bootloader,300K是應用程式。
原理:先要把整頁FLASH的內容搬到RAM中,然後在RAM中改動,然後擦除整頁FLASH,再把改動後的內容寫入原Flash頁。下面程式調試通過。
/*******************************************************************************
* Function Name : I2C_EE_BufferRead
* Description : Reads a block of data from the EEPROM.
* Input :
* -RomAddr
* -NumByteToRead
* -pRomData
* Output : None
* Return : None
*******************************************************************************
void I2C_EE_BufferRead(u16 RomAddr,u16 NumByteToRead,u8 *pRomData)
{
u32 param_flashbase;
u8* ptr;
param_flashbase = 0x8000000+(300+20)*1024;
ptr = (u8*)(param_flashbase + RomAddr);
while( NumByteToRead-- >0)
{
*pRomData = *ptr; //直接賦值即可
printf("0x%x ",*pRomData);
pRomData++;
ptr++;
}
return;
}
/*******************************************************************************
* Function Name : I2C_EE_BufferWrite
* Description : Write a block of data to the EEPROM.
* Input :
* -RomAddr
* -NumByteToRead
* -pRomData
* Output : None
* Return : None
*******************************************************************************
void I2C_EE_BufferWrite(u8 DeviceType,u8 SlaveAddr,u16 RomAddr,u16 NumByteToWrite,u8 *pRomData)
{
uint32_t param_flashbase;
uint32_t tempaddress;
uint32_t startaddress;
uint32_t FlashAddress;
uint32_t datasource;
u8 buf1[PAGE_SIZE];
u8 buf2[PAGE_SIZE];
u32 pagenumber = 0x0;
u32 EraseCounter = 0x0;
u32 i = 0;
FLASH_Status FLASHStatus = FLASH_COMPLETE;
param_flashbase = 0x8000000+(300+20)*1024;
startaddress=tempaddress = param_flashbase+RomAddr;
/*********************起始指標不在Flash頁的開始端*********************
if( (tempaddress%PAGE_SIZE) != 0)
{ printf("startptr not in Page head \r\n");
if( ((startaddress%PAGE_SIZE)+NumByteToWrite) > PAGE_SIZE ) /*超出一頁範圍
{
I2C_EE_BufferRead(0,0,(tempaddress-(tempaddress % PAGE_SIZE)),PAGE_SIZE,buf1); /*把起始地址所在頁的內容讀到記憶體buf1中
memcpy(buf1+(tempaddress % PAGE_SIZE),pRomData,PAGE_SIZE-(tempaddress % PAGE_SIZE)); /*把需要寫入的資料覆蓋到buf1中
while( FLASHStatus == FLASH_ErasePage(tempaddress) ) /*buf1寫入到Flash
{
i=PAGE_SIZE/4;
datasource = (uint32_t)buf1;
FlashAddress = tempaddress-(tempaddress % PAGE_SIZE);
while(i-- >0)
{
FLASH_ProgramWord(FlashAddress,*(uint32_t*)datasource);
if (*(uint32_t*)FlashAddress != *(uint32_t*)datasource)
{
printf("I2C_EE_BufferWrite error!\r\n");
return ;
}
datasource += 4;
FlashAddress += 4;
}
break;
}
NumByteToWrite -= PAGE_SIZE-(startaddress % PAGE_SIZE); 需要寫入位元組數減去,上面覆蓋上去的資料的位元組數
tempaddress += PAGE_SIZE-(tempaddress % PAGE_SIZE); /*把ptr指標指向下一個頁起始位置
if((NumByteToWrite % PAGE_SIZE) != 0) /*末指標不在Flash頁的開始端
{
//讀取1 PAGE 資料到記憶體,修改,然後寫進去
I2C_EE_BufferRead(0,0,tempaddress,PAGE_SIZE,buf2);
memcpy(buf2,pRomData+PAGE_SIZE-startaddress%PAGE_SIZE+NumByteToWrite-NumByteToWrite%PAGE_SIZE,(NumByteToWrite%PAGE_SIZE));
while( FLASHStatus == FLASH_ErasePage( tempaddress+NumByteToWrite) ) /*把buf2寫入到Flash中*
{
i=PAGE_SIZE/4;
datasource = (uint32_t)buf2;
FlashAddress = (tempaddress+NumByteToWrite-(NumByteToWrite % PAGE_SIZE)); /*末地址指標的頁首
while(i-- >0)
{
FLASH_ProgramWord(FlashAddress,*(uint32_t*)datasource);
if (*(uint32_t*)FlashAddress != *(uint32_t*)datasource)
{
printf("I2C_EE_BufferWrite error!\r\n");
return ;
}
datasource += 4;
FlashAddress += 4;
}
break;
}
}
NumByteToWrite -= NumByteToWrite % PAGE_SIZE;
//擦除Flash
pagenumber = NumByteToWrite/PAGE_SIZE;
for (EraseCounter = 0; (EraseCounter < pagenumber) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
{
FLASHStatus = FLASH_ErasePage( tempaddress + PAGE_SIZE*EraseCounter );
}
//寫Flash
datasource = *(uint32_t *)(pRomData+ PAGE_SIZE-(startaddress % PAGE_SIZE) );
FlashAddress = tempaddress;
while( pagenumber-- > 0 )
{
i=PAGE_SIZE/4;
while(i -- >0)
{
FLASH_ProgramWord(FlashAddress,*(uint32_t*)datasource);
if (*(uint32_t*)FlashAddress != *(uint32_t*)datasource)
{
printf("I2C_EE_BufferWrite error!\r\n");
return ;
}
datasource += 4;
FlashAddress += 4;
}
}
}
else /*寫的內容沒有超出一頁範圍
{
printf("FlashWrire --in one page \r\n");
I2C_EE_BufferRead(0,0,(startaddress-(startaddress % PAGE_SIZE)),PAGE_SIZE,buf1); /*把起始地址所在頁的內容讀到記憶體buf1中
memcpy( (buf1+(tempaddress % PAGE_SIZE)),pRomData, NumByteToWrite ); /*把需要寫入的資料覆蓋到buf1中
while( FLASHStatus == FLASH_ErasePage(tempaddress) )
{
i=PAGE_SIZE/4;
datasource = (uint32_t)buf1;
FlashAddress = tempaddress-(tempaddress % PAGE_SIZE);
while(i-- >0)
{
FLASH_ProgramWord(FlashAddress,*(uint32_t*)datasource);
if (*(uint32_t *)FlashAddress != *(uint32_t *)datasource) /*讀取Flash中的資料,看是否寫入正確
{
printf("I2C_EE_BufferWrite error!\r\n");
return ;
}
datasource += 4;
FlashAddress += 4;
}
break;
}
}
}
/*******************起始指標在Flash頁的開始端****************************
else
{ printf("startptr in Page head \r\n");
if((NumByteToWrite % PAGE_SIZE) != 0)
{
//讀取1 PAGE 資料到記憶體,修改,然後寫進去
I2C_EE_BufferRead(0,0,(u16)(tempaddress+NumByteToWrite-(NumByteToWrite % PAGE_SIZE)),PAGE_SIZE,buf1);
printf("already copy to bug1 \r\n");
memcpy(buf1,pRomData+NumByteToWrite-(NumByteToWrite % PAGE_SIZE),(NumByteToWrite % PAGE_SIZE));
//end of debug
}
//擦除Flash
if( (NumByteToWrite%PAGE_SIZE) == 0 )
{
pagenumber = NumByteToWrite/PAGE_SIZE;
}
else
{
pagenumber = NumByteToWrite/PAGE_SIZE + 1;
}
for (EraseCounter = 0; (EraseCounter < pagenumber) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
{
FLASHStatus = FLASH_ErasePage(startaddress + (PAGE_SIZE * EraseCounter));
}
//寫Flash
if( pagenumber == 1) /*只有一頁
{
i=PAGE_SIZE/4;
datasource = (uint32_t)buf1;
FlashAddress = startaddress;
while(i-- >0)
{
FLASH_ProgramWord(FlashAddress,*(uint32_t *)datasource);
if (*(uint32_t *)FlashAddress != *(uint32_t *)datasource)
{
printf("I2C_EE_BufferWrite error!\r\n");
return ;
}
datasource +=4;
FlashAddress +=4;
}
}
else /*很多頁時,先寫前面頁,最後寫buf1
{
while( pagenumber-- > 1 )
{
datasource = (u32)pRomData;
FlashAddress = startaddress;
i=PAGE_SIZE/4;
while(i -- >0)
{
FLASH_ProgramWord( FlashAddress, *(uint32_t *)datasource );
if (*(uint32_t *)FlashAddress != *(uint32_t *)datasource)
{
printf("I2C_EE_BufferWrite error!\r\n");
return ;
}
datasource += 4;
FlashAddress += 4;
}
}
//寫後面的頁
datasource = (uint32_t)buf1;
FlashAddress = startaddress+(pagenumber-1)*PAGE_SIZE;
i=PAGE_SIZE/4;
while(i -- >0)
{
FLASH_ProgramWord( FlashAddress, *(uint32_t *)datasource );
if (*(uint32_t *)FlashAddress != *(uint32_t *)datasource)
{
printf("I2C_EE_BufferWrite error!\r\n");
return ;
}
datasource += 4;
FlashAddress += 4;
}
}
}
}