STM32L151 IAP功能存储区划分

2019-12-20 21:46发布

分享我最近做的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();
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。