基于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<len;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;
}
}
}
超时处理。