📄 flashload.c
字号:
#include "..\Include\FlashLoad.h"
extern int FLH_Program1Word(U16 * addr, U16 val);
extern int FLH_Erase1Sector(U16 * addr);
extern int FLH_Erase1Block(U16 * addr);
extern void FLH_ReadSecID(U16 * ptr);
extern void FLH_WriteSecID(U16 value, U16 offset);
extern void FLH_Erase1Block_Load();
extern void FLH_Erase1Sector_Load();
extern void FLH_Program1Word_Load();
extern void FLH_ReadSecID_Load();
extern void FLH_ProgramSecID_Load();
extern void Test_Delay(U16 num);
// This module is to copy itself to RAM,jump to RAM and to do code update.
//void BootLoader()
//{
//}
void FLH_ReadSecurityID(U16 * ptr)
{
FLH_ReadSecID_Load();
FLH_ReadSecID(ptr);
}
void FLH_Program_SecID(U16 * data_ptr)
{
U16 i;
FLH_ProgramSecID_Load();
for (i=0; i<8; i++)
{
FLH_WriteSecID(data_ptr[i], i+0x10);
}
}
U16 FLH_Program_Word(U16 * addr, U16 val)
{
/* U16 i;
U16 * ptr;
ptr = (U16 *)PROGRAM_WORD_START;
for (i = 0;i<PROGRAM_WORD_LEN; i++){
GBuf[i] = ptr[i];
}
*/
FLH_Program1Word_Load();
return (FLH_Program1Word(addr, val));
}
U16 FLH_Erase_Sector(U16 * addr)
{
/* U16 i;
U16 * ptr;
ptr = (U16 *)ERASE_SECTOR_START;
for (i = 0;i<ERASE_SECTOR_LEN; i++){
GBuf[i] = ptr[i];
}
// Test_Delay(10);
*/
FLH_Erase1Sector_Load();
return (FLH_Erase1Sector(addr));
}
U16 FLH_Erase_Block(U16 * addr)
{
/* U16 i;
U16 * ptr;
ptr = (U16 *)ERASE_BLOCK_START;
for (i = 0;i<ERASE_BLOCK_LEN; i++){
GBuf[i] = ptr[i];
}
*/
FLH_Erase1Block_Load();
return (FLH_Erase1Block(addr));
}
U16 FLH_Program_Long(U16 * addr, U32 val)
{
U16 i;
// U16 * ptr;
U32_HL tmp;
/*
ptr = (U16 *)PROGRAM_WORD_START;
for (i = 0;i<PROGRAM_WORD_LEN; i++){
GBuf[i] = ptr[i];
}
*/
FLH_Program1Word_Load();
tmp.DWord = val;
i = FLH_Program1Word(addr, tmp.HLWord.L);
i += FLH_Program1Word(addr+1, tmp.HLWord.H);
return(i);
}
// program from 1 sector to another sector; at sector begining to sector end
U16 FLH_Program_Sector(U16 * src_ptr, U16 * dest_ptr)
{
U16 i,j;
// U16 * ptr;
U32_HL src, dest;
/*
ptr = (U16 *)PROGRAM_WORD_START;
for (i = 0;i<PROGRAM_WORD_LEN; i++){
GBuf[i] = ptr[i];
}
*/
FLH_Program1Word_Load();
src.DWord = (U32)src_ptr;
src.HLWord.L &= 0xF800;
dest.DWord = (U32)dest_ptr;
dest.HLWord.L &= 0xF800;
src_ptr = (U16 *)src.DWord;
dest_ptr = (U16 *)dest.DWord;
j = 0;
for (i=0; i<SECTOR_SIZE; i++)
{
j += FLH_Program1Word(dest_ptr++, *src_ptr++);
}
return(j);
}
U16 FLH_Program_Data(U16 * src_ptr, U16 * dest_ptr, U16 len)
{
U16 i,j;
// U16 * ptr;
/*
ptr = (U16 *)PROGRAM_WORD_START;
for (i = 0;i<PROGRAM_WORD_LEN; i++){
GBuf[i] = ptr[i];
}
*/
FLH_Program1Word_Load();
j = 0;
for (i=0; i<len; i++)
{
j += FLH_Program1Word(dest_ptr++, *src_ptr++);
}
return(j);
}
// 1 sector for flag; 7 sectors for swap area
// swap area is cyclic to backup sectors
// flag sector is cyclic to record update flag items
// find last index in flag sector, return which item is the last.
// 0 to MAX_FLAG_REC -1, if return MAX_FLAG_REC, the pool is full.
U16 Find_Last_Flag()
{
FLASH_FLAG_REC * ptr;
U16 i;
ptr = (FLASH_FLAG_REC *)SWAP_FLAG;
for (i=0; i<=MAX_FLAG_REC; i++)
{
if ((ptr->flag == 0xffff) && (ptr->addr_ptr == (U16 *)0xffffffff) && (ptr->length == 0xffff))
break;
ptr++;
}
return(i);
}
// to judge if the data block is cross the sector border or not.
// 0: not cross sector border, 1: cross the sector border
U16 Cross_Sector(U16 * addr, U16 len)
{
U32 i;
U16 j,k;
i = (U32)addr;
j = i/SECTOR_SIZE;
k = (i+len)/SECTOR_SIZE;
if (j==k)
return(0);
else
return(1);
}
void FLH_Restore_Update()
{
U16 * buf_ptr1;
U16 * buf_ptr2;
FLASH_FLAG_REC * rec_ptr;
U16 i;
U16 * tmp_ptr;
// find index in flag sector
i = Find_Last_Flag();
if (i==0) // nothing to restore
return;
i = i-1;
rec_ptr = (FLASH_FLAG_REC *)((U32)SWAP_FLAG + i*sizeof(FLASH_FLAG_REC));
if (rec_ptr->flag == 0) // nothing to restore
return;
if ((rec_ptr->flag == FLAG_1S) || (rec_ptr->flag == FLAG_2S))
{
// restore sector 1
buf_ptr1 = (U16 *)SWAP_ADDR + (i%SWAP_REC_MAX)*SECTOR_SIZE;
FLH_Erase_Sector(rec_ptr->addr_ptr);
FLH_Program_Sector(buf_ptr1, rec_ptr->addr_ptr);
if (rec_ptr->flag == FLAG_2S) // restore sector 2
{
buf_ptr2 = (U16 *)SWAP_ADDR + ((i+1)%SWAP_REC_MAX)*SECTOR_SIZE;
tmp_ptr = rec_ptr->addr_ptr+SECTOR_SIZE; // pointer to 2nd sector
FLH_Erase_Sector(tmp_ptr);
FLH_Program_Sector(buf_ptr2, tmp_ptr);
}
FLH_Program_Word((U16 *)rec_ptr, 0); // update flag to be finished
}
}
U16 FLH_Update_Data(U16 * src_ptr, U16 * dest_ptr, U16 len)
{
U16 * buf_ptr1;
U16 * buf_ptr2;
U16 * flag_item_ptr;
U16 i,j,flag_cross;
U32 tmplong;
// find index in flag sector
i = Find_Last_Flag();
if (i==MAX_FLAG_REC) // if no available flag item, erase whole sector.
{
FLH_Erase_Sector((U16 *)SWAP_FLAG);
i = 0;
}
// to judge if 1 sector or 2 sector to be stored
flag_cross = Cross_Sector(dest_ptr, len);
// backup sector 1
buf_ptr1 = (U16 *)SWAP_ADDR + (i%SWAP_REC_MAX)*SECTOR_SIZE;
FLH_Erase_Sector(buf_ptr1);
FLH_Program_Sector(dest_ptr, buf_ptr1);
if (flag_cross) // backup sector 2
{
buf_ptr2 = (U16 *)SWAP_ADDR + ((i+1)%SWAP_REC_MAX)*SECTOR_SIZE;
FLH_Erase_Sector(buf_ptr2);
FLH_Program_Sector(dest_ptr+len, buf_ptr2);
}
// update flag item
flag_item_ptr = (U16 *)SWAP_FLAG + i*sizeof(FLASH_FLAG_REC); //
FLH_Program_Long(flag_item_ptr+1, (U32)dest_ptr);
FLH_Program_Word(flag_item_ptr+3, len);
if (flag_cross)
FLH_Program_Word(flag_item_ptr, FLAG_2S);
else
FLH_Program_Word(flag_item_ptr, FLAG_1S);
// update destination value, erase first, program remainder data + target data;
// update remainder data
tmplong = (U32)dest_ptr;
i = tmplong%SECTOR_SIZE; // if start from sector begining
FLH_Erase_Sector(dest_ptr); // erase first sector
if (i != 0) // not from sector begining
{
FLH_Program_Data(buf_ptr1, dest_ptr-i, i);
}
j = SECTOR_SIZE - (tmplong+len)%SECTOR_SIZE;
if (flag_cross==0) // just 1 sector to be updated
{
FLH_Program_Data(src_ptr, dest_ptr, len); // update target data
if (j != 0)
FLH_Program_Data(buf_ptr1+i+len, dest_ptr+len, j);
}
else // 2 sectors to be updated, cross border
{
FLH_Erase_Sector(dest_ptr+len); // erase 2nd sector
FLH_Program_Data(src_ptr, dest_ptr, len); // program can cross the border
// if cross border, j should not equal to 0
// buf_ptr2 do not necessary to be next to buf_ptr1, it might turn to swap area's beginning
FLH_Program_Data(buf_ptr2+SECTOR_SIZE-j, dest_ptr+len, j);
}
i = FLH_Program_Word(flag_item_ptr, 0); // update flag to be finished
return(i);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -