分享我最近做的STM32L151 IAP升级中的存储区划分说明(详见附件),并附上主要代码,注释说明写的不多(比较懒)写的不好(水平有限),欢迎大家吐槽!
#define FLAG_APP_BEGIN_ADDR (uint32_t)0x08004000
#define INFO_APP_DL_STATE_ADDR (uint32_t)0x08014000
#define FLAG_SINGLE_SIZE 16
//读第一条FLAG数据
static void ReadFlagFirstMsg(void)
{
FLASH_ReadBytes(FLAG_APP_BEGIN_ADDR,flagData.flag_first_msg,FLAG_SINGLE_SIZE);
}
void ReadFlagLatestMsg(void)
{
GetFlagNewRowAddr();
if(flagData.flag_new_row_addr == FLAG_APP_BEGIN_ADDR)
FLASH_ReadBytes(FLAG_APP_BEGIN_ADDR,flagData.flag_latest_msg,FLAG_SINGLE_SIZE);
else
FLASH_ReadBytes(flagData.flag_new_row_addr-0x10,flagData.flag_latest_msg,FLAG_SINGLE_SIZE);
}
void WriteFlagLatestMsg(uint8_t *pdata,FLAG_WRITE_DEF fdat)
{
uint32_t addr;
if(fdat == FLAG_WRITE_ADD)
{
addr = flagData.flag_new_row_addr;
flagData.flag_new_row_addr += FLAG_SINGLE_SIZE;
//GetFlagNewRowAddr();
}
else
{
addr = flagData.flag_new_row_addr;
if(addr > FLAG_APP_BEGIN_ADDR)addr -= 0x10;
}
FLASH_Unlock();
FLASH_WriteBytes(addr,pdata,FLAG_SINGLE_SIZE);
FLASH_Lock();
}
/*****************************************************************************************/
//如下是下载状态表操作的函数
/*****************************************************************************************/
//获取下载状态表最新包标志的位置
uint8_t GetInfoPkgNum(uint16_t info_pkg_pos)
{
uint8_t tmp = FLASH_ReadChar(INFO_APP_DL_STATE_ADDR+info_pkg_pos);
return tmp;
}
static uint8_t GetInfoPkgNum(uint16_t info_pkg_pos)
{
uint8_t tmp = FLASH_ReadChar(INFO_APP_DL_STATE_ADDR+info_pkg_pos);
return tmp;
}
static uint8_t CheckInfoTableRowPkgState(uint8_t pkgnum)
{
if(pkgnum == 0xFF)return 1; //8个包下载完成
else return 0;
}
// 返回值 0:数据全是0xFF 非0:具体位置
static uint8_t CheckInfoTableRowNoPkgPos(uint8_t pkgnum)
{
uint8_t pos;
uint8_t tmp = pkgnum;
for(pos=1;pos<9;pos++)
{
if(!(tmp&0x01))return(pos); //从8个包中的第1个包开始检查
tmp >>= 1;
}
}
static void WriteInfoNewBitDownloadTable(uint16_t pos)
{
uint16_t addr_offset = (pos-1)>>3;
uint8_t tmp;
tmp = (pInfoData->table_latest_row_byte<<1)|1;
pInfoData->table_latest_row_byte = tmp;
FLASH_WriteBytes(INFO_APP_DL_STATE_ADDR+addr_offset,&tmp,1);
return;
}
/*****************************************************************************************
返回值 0:从未下载
0xFFFF: 全部已下载 (总包数不大于该值)
非0非0xFFFF:从0开始具体第几个包未下载
*****************************************************************************************/
uint16_t GetInfoNoDownloadPkgNum(void)
{
uint16_t info_pkg_pos;
uint8_t pkgnum,nopkgpos;
uint32_t pkgsize = (uint16_t)pFlagData->flag_latest_msg[FLAG_OFFSET_APP_SIZE]<<8;
pkgsize |= pFlagData->flag_latest_msg[FLAG_OFFSET_APP_SIZE+1];
if(pkgsize == 0)return 0;
for(info_pkg_pos=0;info_pkg_pos<pkgsize;info_pkg_pos++)
{
pkgnum = GetInfoPkgNum(info_pkg_pos); //获取下载状态表中8个包的状态
if(CheckInfoTableRowPkgState(pkgnum))continue; //如果状态表中8个包都下载完成,继续下8个包检查
pInfoData->table_latest_row_byte = pkgnum;
nopkgpos = CheckInfoTableRowNoPkgPos(pkgnum); //检查下载状态表中哪个包还没完成下载
if(nopkgpos)
return((info_pkg_pos*8)+nopkgpos); //返回未下载包的序列号
}
return 0xFFFF;
}
//写入新接收包的标志位
void SetInfoNewPkgBitToTable(void)
{
static uint16_t tmp;
tmp = GetInfoNoDownloadPkgNum();
FLASH_Unlock();
WriteInfoNewBitDownloadTable(tmp);
FLASH_Lock();
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
__interrupts_disable();
一周热门 更多>