一、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.6参数定义部分:
#define UpdataStatusAddress Sector2StartAddress
#define APP_START_ADDRESS Sector3StartAddress
typedef enum{
WaitDataNum = 0,
WriteDataNum,
RunAPPNum,
}BootLoaderTaskNUMDef;
BootLoaderTaskNUMDef BootLoaderTaskNUM;
1.7keil设置如下:
我使用的是STM32F407VET6
二、APP部分
单纯用串口输出HELLO,关于keil的设置如下:
三、演示