#include "bootloader_iap.h" #include "flash.h" #include "off_chip_flash.h" #include "delay.h" #include "mbcrc.h" BOOTLOAD_PARA_STRUCT __attribute__ ((aligned (4))) bootload_para_g = {0}; uint8_t __attribute__ ((aligned (4))) FlashWrBuf[512] = {0}; #define IAP_UPDATA_FLAG (0x12345678) /*Ô¶³ÌÉý¼¶È«²¿Ð£Ñé³É¹¦Èí¼þ¸´Î»*/ 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) { /*¹Ø±ÕÈ«²¿ÍâÉè*/ delay_ms(500); RMU->SOFTRST = 0x5C5CAABB; //Èí¼þ¸´Î» } } ErrorStatus_STM32 IapBootload_WriteCfgFlash_Handler(void) { if(Flash_AppPageErase(BOOTLOAD_CONFIG_START_ADDRESS) != SUCCESS_0) return ERROR_1; bootload_para_g.boot_update_flag = IAP_UPDATA_FLAG;//УÑéͨ¹ý±êÖ¾ //дÈë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(bootload_para_g.boot_update_flag))) return (ErrorStatus_STM32)1; memcpy(&bootload_para_g,pInputData,data_len); /*ÑéÖ¤CFGµÄÕýÈ·ÐÔ*/ if(bootload_para_g.diff_prog_start_addrBOOTLOAD_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_addrBOOTLOAD_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; E2P_PWR_ON; //²Á³ý¸ø¶¨ÆðʼµØÖ·ºÍ´óСµÄ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(); //Çåϵͳ¿´ÃŹ· } E2P_PWR_OFF; //²Á³ý²îÒì³ÌÐò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; } return result; } /****************************************** * 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) { 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)//´úÂë²»Äܳ¬¹ý×î´ó³¤¶È return (ErrorStatus_STM32)3; if((bootload_para_g.diff_prog_start_addr+offset_addr)> 9;// µÈ¼ÛÓÚ / 512 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(); //Çåϵͳ¿´ÃŹ· } 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(); //Çåϵͳ¿´ÃŹ· //гÌÐòУÑé crc16 =0xFFFF; page_len = bootload_para_g.new_prog_length/BOOTLOAD_PAGE_SIZE; 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(); //Çåϵͳ¿´ÃŹ· } 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; E2P_PWR_OFF; 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; }