#include "bootloader_iap.h"
|
#include "flash.h"
|
#include "off_chip_flash.h"
|
#include "delay.h"
|
#include "mbcrc1.h"
|
#include "system_general_para.h"
|
|
BOOTLOAD_PARA_STRUCT __attribute__ ((aligned (4))) bootload_para_g = {0};
|
|
uint8_t __attribute__ ((aligned (4))) FlashWrBuf[512] = {0};
|
|
#define IAP_UPDATA_FLAG (0x12345678)
|
#define IAP_BSDIFF_LZMA_UPDATA_FLAG (0x87654321)
|
|
/*Ô¶³ÌÉý¼¶È«²¿Ð£Ñé³É¹¦Èí¼þ¸´Î»*/
|
void OTA_UpdataResetHandler(void)
|
{
|
BOOTLOAD_PARA_STRUCT temp_boot_para = {0};
|
memcpy((uint8_t *)&temp_boot_para,(uint8_t *)BOOTLOAD_CONFIG_START_ADDRESS, BOOTLOAT_PARA_SIZE);
|
if(temp_boot_para.boot_update_flag == IAP_UPDATA_FLAG)
|
{
|
/*¹Ø±ÕÈ«²¿ÍâÉè*/
|
__disable_irq();//¹Ø±ÕÈ«¾ÖÖжÏʹÄÜ
|
delay_ms(100);
|
RMU->SOFTRST = 0x5C5CAABB; //Èí¼þ¸´Î»
|
}
|
}
|
|
uint8_t lzma_flag = 0; // ÕâÊÇΪÁ˱£ÁôÔÀ´µÄÁ÷³ÌÉèÖõģ¬
|
// Óë´ËÓйصĽÔΪ´ËÓÃ;£¬²»ÐèÒª±£ÁôÔÁ÷³ÌʱӦɾȥ
|
|
|
ErrorStatus_STM32 IapBootload_WriteCfgFlash_Handler(void)
|
{
|
if(Flash_AppPageErase(BOOTLOAD_CONFIG_START_ADDRESS) != SUCCESS_0)
|
return ERROR_1;
|
if(lzma_flag == 0)
|
{
|
bootload_para_g.boot_update_flag = IAP_UPDATA_FLAG;//УÑéͨ¹ý±êÖ¾
|
}else if(lzma_flag == 1){
|
bootload_para_g.boot_update_flag = IAP_BSDIFF_LZMA_UPDATA_FLAG;
|
// lzma_flag = 0;
|
}else{
|
bootload_para_g.boot_update_flag = 0x55555555; // Õâ¸ö²»Ó¦¸Ã·¢Éú
|
}
|
//дÈëflash
|
if(Flash_App_Write_String(BOOTLOAD_CONFIG_START_ADDRESS,(uint32_t *)&bootload_para_g, BOOTLOAT_PARA_SIZE)!= SUCCESS_0)//½«cfgдÈëflash
|
return ERROR_1;
|
return SUCCESS_0;
|
}
|
|
/******************************************
|
* func: BootLoader_IapConfigSetHander
|
* desc: IAPÏà¹ØµÄһЩÅäÖòÎÊýÉèÖÃ
|
* input: pInputData£º²ÎÊýÊý¾Ý£¬Ïê¼ûBOOTLOAD_PARA_STRUCT½á¹¹Ìå
|
data_len£ºÊý¾Ý³¤¶È
|
* output: none
|
* return: SUCCESS_0£º³É¹¦ ERROR_1/ÆäËû£ºÊ§°Ü
|
*****************************************/
|
ErrorStatus_STM32 BootLoader_IapConfigSetHander(uint8_t *pInputData,uint32_t data_len)
|
{
|
ErrorStatus_STM32 result = SUCCESS_0;
|
uint16_t crc_16 = 0;
|
uint32_t crc_crc = 0,offset = 0;
|
if(data_len != (BOOTLOAT_PARA_SIZE - SIZEOF_OF(BOOTLOAD_PARA_STRUCT,boot_update_flag)))
|
return (ErrorStatus_STM32)1;
|
memcpy(&bootload_para_g,pInputData,data_len);
|
/*ÑéÖ¤CFGµÄÕýÈ·ÐÔ*/
|
if(bootload_para_g.diff_prog_start_addr<BOOTLOAD_DIFF_PROG_START_ADDRESS)//²îÒì³ÌÐòÆðʼµØÖ·
|
return (ErrorStatus_STM32)2;
|
if(bootload_para_g.diff_prog_length>BOOTLOAD_DIFF_PROG_LEN_MAX)//²îÒì³ÌÐò×î´ó³¤¶È
|
return (ErrorStatus_STM32)3;
|
if(bootload_para_g.diff_prog_map_length>512)//²îÒì³ÌÐò±í×î´ó³¤¶È
|
return (ErrorStatus_STM32)4;
|
if(bootload_para_g.user_porg_start_addr<BOOTLOAD_USER_PROG_START_ADDRESS)//Óû§³ÌÐòÆðʼµØÖ·
|
return (ErrorStatus_STM32)5;
|
if(bootload_para_g.user_prog_length>BOOTLOAD_USER_PROG_LEN_MAX)//Óû§³ÌÐò×î´ó³¤¶È
|
return (ErrorStatus_STM32)6;
|
if(bootload_para_g.new_prog_length>BOOTLOAD_USER_PROG_LEN_MAX)//гÌÐò×î´ó³¤¶È
|
return (ErrorStatus_STM32)7;
|
|
|
/*ÉÏλ»úͨ¹ýÀϳÌÐòµÄhexÎļþ¼ÆËã³öcrcÖµ£¬²¢Í¨¹ýUIC_APP_CONFIGÃüÁîÏ·¢µ½É豸¶ËÖÐ*/
|
crc_16 = usMBCRC16(0xFFFF,(unsigned char*)BOOTLOAD_USER_PROG_START_ADDRESS, bootload_para_g.user_prog_length);
|
crc_crc = (crc_16 << 16) | crc_16;
|
if (crc_crc != bootload_para_g.user_prog_crc16)//ÓëÅäÖÃÎļþÖеijÌÐòCRCÖµ½øÐбȶÔ
|
return (ErrorStatus_STM32)8;
|
|
OUT_FLASH_CTRL_ENABLE;
|
//²Á³ý¸ø¶¨ÆðʼµØÖ·ºÍ´óСµÄFlash£¬Æ¬Íâflash
|
for (offset = 0; offset < bootload_para_g.diff_prog_length; offset += OUT_FLASH_SECTOR_SIZE)
|
{
|
Flash_OUT_Erase_Sector((BOOTLOAD_DIFF_PROG_START_ADDRESS + offset)/OUT_FLASH_SECTOR_SIZE);
|
IWDT_Clr(); //Çåϵͳ¿´ÃŹ·
|
}
|
OUT_FLASH_CTRL_DISABLE;
|
//²Á³ý²îÒì³ÌÐòmap±í£¬Æ¬ÄÚflash
|
for (offset = 0; offset < bootload_para_g.diff_prog_map_length; offset += BOOTLOAD_PAGE_SIZE)
|
{
|
if(Flash_AppPageErase(BOOTLOAD_DIFF_SECTOR_MAP_ADDRESS + offset)!= SUCCESS_0)
|
return (ErrorStatus_STM32)9;
|
}
|
lzma_flag = 1;
|
return result;
|
}
|
|
ErrorStatus_STM32 BootLoader_IapConfigLzmaSetHander(uint8_t *pInputData,uint32_t data_len)
|
{
|
lzma_flag = 1;
|
return BootLoader_IapConfigSetHander(pInputData, data_len);
|
}
|
/******************************************
|
* func: BootLoader_IapDiffDataHandler
|
* desc: ÕýʽдÈë²îÒìÊý¾Ý£¨´æ´¢ÔÚÆ¬ÍâFlash£©
|
* input: pInputData£º²îÒìÊý¾Ý£¬ÓÉÉÏλ»ú´ÓHexÎļþÌáÈ¡
|
offset_addr£ºÆ«ÒƵØÖ·
|
data_len£ºÊý¾Ý³¤¶È
|
* output: none
|
* return: SUCCESS_0£º³É¹¦ ERROR_1/ÆäËû£ºÊ§°Ü
|
*****************************************/
|
ErrorStatus_STM32 BootLoader_IapDiffDataHandler(uint8_t *pInputData,uint32_t offset_addr,uint16_t data_len)
|
{
|
int i=0;
|
ErrorStatus_STM32 result = SUCCESS_0;
|
//дÈ볤¶ÈÄÜ´óÓÚÒ³³¤¶È,±¾À´Ó¦¸Ã²»ÄÜ´óÓÚOUT_FLASH_SECTOR_SIZE£¬µ«ÊÇÈÔÈ»²ÉÓÃÒ»´Î×î´ó512×Ö½Ú£¨Æ¬ÄÚµÄÒ»¸öÒ³Çø´óС£©
|
if(data_len > BOOTLOAD_PAGE_SIZE)
|
return (ErrorStatus_STM32)2;
|
|
if(offset_addr>=BOOTLOAD_DIFF_PROG_LEN_MAX || offset_addr + data_len >= BOOTLOAD_DIFF_PROG_LEN_MAX)//´úÂë²»Äܳ¬¹ý×î´ó³¤¶È
|
return (ErrorStatus_STM32)3;
|
|
if((bootload_para_g.diff_prog_start_addr+offset_addr)<BOOTLOAD_DIFF_PROG_START_ADDRESS)
|
return (ErrorStatus_STM32)4;
|
if((bootload_para_g.diff_prog_start_addr+offset_addr+data_len)>(BOOTLOAD_DIFF_PROG_START_ADDRESS+BOOTLOAD_DIFF_PROG_LEN_MAX))
|
return (ErrorStatus_STM32)5;
|
//дÈëflash
|
memcpy(FlashWrBuf, pInputData, data_len);//¶Á³öÊý¾Ý 4×Ö½Ú¶ÔÆë
|
//дÈëÆ¬Íâflash
|
OUT_FLASH_CTRL_ENABLE;
|
if(offset_addr == 0){ // ÉÏλ»úËÆºõ´«ÊäµÄ»¹ÊÇ512×Ö½Ú¶ÔÆëµÄ³¤¶È£¬µÈ´ýÉÏλ»úÐÞ¸´ºó¿Éɾ
|
bootload_para_g.diff_prog_length = 0;
|
}
|
Out_Flash_MultipleWrite(FlashWrBuf,BOOTLOAD_DIFF_PROG_START_ADDRESS + offset_addr,data_len);
|
OUT_FLASH_CTRL_DISABLE;
|
bootload_para_g.diff_prog_length += data_len;
|
return result;
|
}
|
|
|
/******************************************
|
* func: BootLoader_IapConfigCheckHandler
|
* desc: IAPÍê³ÉºóºË²éÊý¾ÝºÍ²ÎÊý
|
* input: none
|
* output: none
|
* return: SUCCESS_0£º³É¹¦ ERROR_1/ÆäËû£ºÊ§°Ü
|
*****************************************/
|
ErrorStatus_STM32 BootLoader_IapConfigCheckHandler(void)
|
{
|
ErrorStatus_STM32 result = SUCCESS_0;
|
uint32_t crc16 = 0xFFFF;
|
uint16_t page_len = 0,i = 0,j = 0;
|
uint8_t dataBuf[512],map;
|
OUT_FLASH_CTRL_ENABLE;
|
|
if(lzma_flag == 0)
|
{
|
//²îÒì³ÌÐòУÑé,´ÓÍâÆ¬flash¶ÁÈ¡,Ôݶ¨Ò»´Î¶ÁÈ¡512×Ö½Ú£¬Ó¦¸Ã¿ÉÒÔ¶ÁÈ¡¸ü¶à
|
page_len = bootload_para_g.diff_prog_length >> 9;// µÈ¼ÛÓÚ / 512
|
OUT_FLASH_CTRL_ENABLE;
|
for(i = 0; i < page_len;i++)
|
{
|
Out_Flash_MultipleRead(dataBuf,BOOTLOAD_DIFF_PROG_START_ADDRESS + i * BOOTLOAD_PAGE_SIZE,BOOTLOAD_PAGE_SIZE);
|
crc16 = usMBCRC16(crc16, dataBuf, 512);
|
//flash¶Á512×Ö½Ú´ó¸Å10ms
|
IWDT_Clr(); //Çåϵͳ¿´ÃŹ·
|
}
|
OUT_FLASH_CTRL_DISABLE;
|
crc16 |= (crc16 << 16);
|
if(crc16 != bootload_para_g.diff_prog_crc16)//ÓëÅäÖÃÎļþÖеijÌÐòCRCÖµ½øÐбȶÔ
|
result = (ErrorStatus_STM32)1;
|
}
|
//²îÒì³ÌÐòmap±íУÑé
|
crc16 = usMBCRC16(0xFFFF,(unsigned char*)BOOTLOAD_DIFF_SECTOR_MAP_ADDRESS, bootload_para_g.diff_prog_map_length);
|
crc16 |= (crc16 << 16);
|
if (crc16 != bootload_para_g.diff_prog_map_crc16)//ÓëÅäÖÃÎļþÖеijÌÐòCRCÖµ½øÐбȶÔ
|
result = (ErrorStatus_STM32)2;
|
//¾É³ÌÐòУÑé
|
crc16 = usMBCRC16(0xFFFF,(unsigned char*)BOOTLOAD_USER_PROG_START_ADDRESS, bootload_para_g.user_prog_length);
|
crc16 |= (crc16 << 16);
|
if (crc16 != bootload_para_g.user_prog_crc16)//ÓëÅäÖÃÎļþÖеijÌÐòCRCÖµ½øÐбȶÔ
|
result = (ErrorStatus_STM32)3;
|
IWDT_Clr(); //Çåϵͳ¿´ÃŹ·
|
if(lzma_flag == 0)
|
{
|
//гÌÐòУÑé
|
crc16 =0xFFFF;
|
page_len = bootload_para_g.new_prog_length/BOOTLOAD_PAGE_SIZE;
|
OUT_FLASH_CTRL_ENABLE;
|
for(i = 0;i < page_len;i++)
|
{
|
map = *(unsigned char *)(BOOTLOAD_DIFF_SECTOR_MAP_ADDRESS+i/8);
|
if((map&(1<<(i%8)))==0)//ÓвîÒìÒ³£¬ÐèÒª´ÓƬÍâ¶Á
|
{
|
Out_Flash_MultipleRead(dataBuf,BOOTLOAD_DIFF_PROG_START_ADDRESS + j * BOOTLOAD_PAGE_SIZE,BOOTLOAD_PAGE_SIZE);
|
crc16 = usMBCRC16(crc16, dataBuf, BOOTLOAD_PAGE_SIZE);
|
j++;
|
}
|
else
|
crc16 = usMBCRC16(crc16, (unsigned char *)(BOOTLOAD_USER_PROG_START_ADDRESS+i*BOOTLOAD_PAGE_SIZE), BOOTLOAD_PAGE_SIZE);
|
IWDT_Clr(); //Çåϵͳ¿´ÃŹ·
|
}
|
OUT_FLASH_CTRL_DISABLE;
|
crc16 |= (crc16 << 16);
|
if (crc16 != bootload_para_g.new_prog_crc16)//ÓëÅäÖÃÎļþÖеijÌÐòCRCÖµ½øÐбȶÔ
|
result = (ErrorStatus_STM32)4;
|
}
|
if(IapBootload_WriteCfgFlash_Handler() != SUCCESS_0)
|
result = (ErrorStatus_STM32)5;
|
OUT_FLASH_CTRL_DISABLE;
|
return result;
|
}
|
|
/******************************************
|
* func: BootLoader_IapDiffMapSetHandler
|
* desc: IAPÏà¹ØµÄ²îÒì±í²ÎÊýÉèÖÃ
|
* input: pInputData£º²ÎÊýÊý¾Ý£¬Ïê¼ûÉÏλ»úÐÒé
|
offset_addr£ºÆ«ÒƵØÖ·
|
data_len£ºÊý¾Ý³¤¶È
|
* output: none
|
* return: SUCCESS_0£º³É¹¦ ERROR_1/ÆäËû£ºÊ§°Ü
|
*****************************************/
|
ErrorStatus_STM32 BootLoader_IapDiffMapSetHandler(uint8_t *pInputData,uint32_t offset_addr,uint16_t data_len)
|
{
|
ErrorStatus_STM32 result = SUCCESS_0;
|
if(data_len > 512) //²îÒì±íÊý¾Ý²»ÄÜ´óÓÚ512£¨Ò³£©
|
return (ErrorStatus_STM32)2;
|
if(offset_addr >= 512)//map²»Äܳ¬¹ý×î´ó³¤¶È
|
return (ErrorStatus_STM32)3;
|
|
memcpy(FlashWrBuf, pInputData, data_len);//¶Á³öÊý¾Ý 4×Ö½Ú¶ÔÆë
|
if(Flash_App_Write_String(BOOTLOAD_DIFF_SECTOR_MAP_ADDRESS + offset_addr,(uint32_t *)&FlashWrBuf, data_len)!= SUCCESS_0)
|
return (ErrorStatus_STM32)5;
|
return result;
|
}
|