基于STM32的IAP试验,试验单片机STM32F407VET6

一、BOOT程序

BOOT程序的步骤就是接收数据、向目标地址写入数据、跳转到目标地址运行APP程序。

1.1BOOT处理函数,如下

void BootLoaderTask()
{
    u32 app_addr = APP_START_ADDRESS;
    switch(BootLoaderTaskNUM)
    {
        case WaitDataNum:{    
//1s内检查是否收到.bin数据,如果收到就开始写入,无校验,单纯的用串口助手传输        
            if(getdataflag == 1)
            {
                getdataflag = 0;
                if(flashdatacounter == 0)
                {
                    Myprintf("waiting data!\r\n");
                    BootLoaderTaskNUM = WaitDataNum;
                    s_counter = 0;
                    getdataflag = 0;
                }
                else
                {
                    s_counter = 0;
                    getdataflag = 0;
                    BootLoaderTaskNUM = WriteDataNum;
                }
            }
            
        }break;
        case WriteDataNum:{
            Myprintf("write data!\r\n");
            if(appwrite(app_addr,flash_data,flashdatacounter) == 1)
            {
                BootLoaderTaskNUM = RunAPPNum;
                Myprintf("write data ok!\r\n");
            }
            else
            {
                Myprintf("write data fail!\r\n");
                flashdatacounter = 0;
                BootLoaderTaskNUM = WaitDataNum;
            }
            
        }break;
        case RunAPPNum:{
            Myprintf("start app...\r\n");
            if (!jump_app(app_addr)) 
            {
                    Myprintf("no program\r\n");
            }
            Myprintf("start app failed\r\n");
            break;
        }break;
    }
}

接收数据部分无校验,直接用串口助手接收,1s判断一次数据是否接收结束.

1.2 定时器部分:

void TIM2_IRQHandler(void)   //200ms
{
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != 0) 
    {
      TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  
        s_counter++;
        if(s_counter>5)
        {
            s_counter = 0;
            getdataflag = 1;
        }
        else
        {
            getdataflag = 0;
        }
    }
}

1.3 串口接收部分:

void USART1_IRQHandler(void)                    //串口1中断服务程序
{
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  
    {
         USART_ClearITPendingBit(USART1, USART_IT_RXNE);
         res1 =USART_ReceiveData(USART1);   
        s_counter = 0;
        flash_data[flashdatacounter] = res1;
        flashdatacounter++;
  } 
}

1.4 flash擦除、写入程序:

#define Sector0StartAddress     0x08000000//16KB
#define Sector1StartAddress     0x08004000//16KB
#define Sector2StartAddress     0x08008000//16KB
#define Sector3StartAddress     0x0800C000//16KB
#define Sector4StartAddress     0x08010000//64KB
#define Sector5StartAddress     0x08020000//128KB
#define Sector6StartAddress     0x08040000//128KB
#define Sector7StartAddress     0x08060000//128KB
#define Sector8StartAddress     0x08080000//128KB
#define Sector9StartAddress     0x080A0000//128KB
#define Sector10StartAddress     0x080C0000//128KB
#define Sector11StartAddress     0x080E0000//128KB
#define SectorEndAddress             0x080FFFFF//128KB

unsigned short int SectorSelect(unsigned int addr)
{
    unsigned short int rbdata;
    if((addr>=Sector0StartAddress)&&(addr<Sector1StartAddress)) rbdata = FLASH_Sector_0;
    else if((addr>=Sector1StartAddress)&&(addr<Sector2StartAddress)) rbdata = FLASH_Sector_1;
    else if((addr>=Sector2StartAddress)&&(addr<Sector3StartAddress)) rbdata = FLASH_Sector_2;
    else if((addr>=Sector3StartAddress)&&(addr<Sector4StartAddress)) rbdata = FLASH_Sector_3;
    else if((addr>=Sector4StartAddress)&&(addr<Sector5StartAddress)) rbdata = FLASH_Sector_4;
    else if((addr>=Sector5StartAddress)&&(addr<Sector6StartAddress)) rbdata = FLASH_Sector_5;
    else if((addr>=Sector6StartAddress)&&(addr<Sector7StartAddress)) rbdata = FLASH_Sector_6;
    else if((addr>=Sector7StartAddress)&&(addr<Sector8StartAddress)) rbdata = FLASH_Sector_7;
    else if((addr>=Sector8StartAddress)&&(addr<Sector9StartAddress)) rbdata = FLASH_Sector_8;
    else if((addr>=Sector9StartAddress)&&(addr<Sector10StartAddress)) rbdata = FLASH_Sector_9;
    else if((addr>=Sector10StartAddress)&&(addr<Sector11StartAddress)) rbdata = FLASH_Sector_10;
    else if((addr>=Sector11StartAddress)&&(addr<=SectorEndAddress)) rbdata = FLASH_Sector_11;
    else rbdata = 0xffff;
    return rbdata;
}

unsigned char FlashErase(unsigned int APPstartaddr,unsigned int APPendaddr)
{
    unsigned short int EraseStartSector,EraseEndSector ;
    unsigned char counter = 0;
    EraseStartSector = SectorSelect(APPstartaddr);
    EraseEndSector = SectorSelect(APPendaddr);
    if((EraseEndSector == 0xffff)||(EraseEndSector == 0xffff)) return 0;
    else 
    {
        FLASH_Unlock();
        while(EraseStartSector<EraseEndSector)
        {
            if(FLASH_EraseSector(EraseStartSector,VoltageRange_3) == FLASH_COMPLETE)
            {
                EraseStartSector +=8;
            }
            else
            {
                counter++;
            }
            if(counter>=10)    break;
        }
        FLASH_Lock();
        if(EraseStartSector<EraseEndSector) return 0;
        else return 1;
    }
}
unsigned char FlashWrite(unsigned int APPstartaddr,unsigned char *appdata,unsigned int appdatalength)
{
    unsigned int counter = 0,addrtemp;
    unsigned char faultcounter = 0;
    addrtemp = APPstartaddr;
    FLASH_Unlock();
    while(counter<appdatalength)
    {
        if(FLASH_ProgramByte(addrtemp,appdata[counter]) == FLASH_COMPLETE)
        {
            counter++;
            addrtemp++;
        }
        else
        {
            faultcounter ++;
        }
        if(faultcounter>=10)break;
    }
    FLASH_Lock();
    if(counter<appdatalength) return 0;
    else return 1;
}
unsigned char appwrite(unsigned int  writeaddress,unsigned char *pdata,unsigned int  pdatalength)
{
    if(FlashErase(APP_START_ADDRESS,APP_END_ADDRESS) == 0) return 0;
    if(FlashWrite(writeaddress,pdata,pdatalength) == 0) return 0;
    return 1;
}

1.5地址跳转部分在https://blog.csdn.net/u012028387/article/details/148676032?spm=1001.2014.3001.5501

1.6参数定义部分:

#define UpdataStatusAddress Sector2StartAddress 
#define  APP_START_ADDRESS Sector3StartAddress

typedef enum{
	WaitDataNum = 0,
	WriteDataNum,
	RunAPPNum,
}BootLoaderTaskNUMDef;
BootLoaderTaskNUMDef BootLoaderTaskNUM;

1.7keil设置如下:

我使用的是STM32F407VET6

二、APP部分

单纯用串口输出HELLO,关于keil的设置如下:

三、演示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值