基于STM32F407的bootloader、IAP、Flash_APP、上位机设计(一)

基于STM32F407的bootloader、IAP、Flash_APP、上位机设计

 

第一部分:Bootloader、IAP设计

前期准备:

一、硬件:STM32F407VET6板一块,IAP使用串口通信,板上需引出串口或有DB9接口都行(如果不使用串口,使用其他协议均可)。

二、软件:KEIL4.73版本,关于IAP读写FLASH的源代码是使用战舰的源码,共有iap、stmflash、sys等文件,上位机软件设计使用QT5.5。

 

工作开始:

1.首先建立工程,配置和普通工程一样即可,能够正常的跑程序。

2.程序初始化LED(看个人需不需要),串口(可选其它通信方式),定时器(必须要)。

3.首先判定boot模式,0为Boot,1为APP。

   bsp_InitLed();        
    
    RcvProcess.RcvDownEna=0;

    if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_9)==1){
            
        if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)
        {    
            iap_load_app(FLASH_APP1_ADDR);//Ö´ÐÐFLASH APP´úÂë
            
        }
        
    }
    else {
              

        bsp_Init();        
    }

在PA9为1时,将FALSH跳转到APP下,#define FLASH_APP1_ADDR        0x08010000 

4.串口通信和下载规则

串口通信上面自己做了一个简单的协议

串口协议

帧头:0XAA

帧尾:0X0D

CRC校验:8位,帧头到校验前的和。

协议规则

帧头

设备号

命令

数据包长度

数据长度

数据0

............

数据n

CRC校验

帧尾

0XAA

0X01

0X01

0x01

N

 

 

 

 

0X0D

 

命令号

名字

意义

读写

0x01

读设备地址

读取该设备设备号

R

0x02

读取设备版本

读取该设备的bootload版本

R

0x03

读取软件版本

读取该设备的APP版本

R

0x04

读取硬件版本

读取该设备的硬件版本

R

0x05

在线下载状态

读取该状态是否允许在线下载更新,0为非,1为真

R

0x06

下载

将bin文件下载到系统内,0为失败,6为成功

R/W

0x07

下载完成状态 返回07位成功,其它位失败 R

下载的时序位

0x05读取下载状态,看是否允许在线更新,判断条件自行设计。

0X06下载,下载的数据是分包下载,每一包都会有100个数据,也可以做成一包其它个数据,最后一个数据包数据长度是不同的,但最终都是根据协议的数据长度来保存。

                       for(i=0;i                         {
                            aRxBuffer[PackNum*100+i]=Msg[i];
                            RcvProcess.RcvLen++;
                        }

0x07下载完成状态,当所有的数据下载完毕,上位机将再发一次完成状态,以表示数据发送完毕,作为截止标志,下位机就可以直接保存到FLASH,iap_write_appbin(FLASH_APP1_ADDR1,aRxBuffer,RcvProcess.RcvLen);保存数据到flash。

5.协议包的读取

一个协议包数据有长有短,如何能有效的识别是否为一包数据呢?

当然是时间,假设通信波特率为115200,那么连续的两个bit间隔时间是1/115200秒,因此可以计算出每个间隔的包是差多少,然后根据定时间做一个超时处理,将再接收到的数据放到下一个 包里面,我一般用50us做超时,时间可以直接算个大概即可。

res = USART_ReceiveData(USARTx);
            RcvProcess.RcvData[RcvProcess.RcvFifoCNT].RcvData[RcvProcess.RcvData[RcvProcess.RcvFifoCNT].RcvLen++]=res;

收到数据保存。

void RcvReadTimeOut()
{
    if(RcvProcess.RcvEnable==1)
    {
        if(--RcvProcess.RcvTimeCNT==0)
        {
                
                RcvDataProcess(RcvProcess.RcvData[RcvProcess.RcvFifoCNT]);
                if(RcvProcess.RcvEnable==1)
                    RcvProcess.RcvFifoCNT++;
                if(RcvProcess.RcvFifoCNT>9)
                    RcvProcess.RcvFifoCNT=0;
                RcvProcess.RcvData[RcvProcess.RcvFifoCNT].RcvLen=0;
                RcvProcess.RcvEnable=0;
        }
    }  
}

超时处理。

 

你可能感兴趣的:(STM32)