#include "gd32e23x.h" #include "systick.h" #include #include "main.h" #include "Fwdgt.h" #include "mb.h" #include "Led.h" #include "Key.h" #include "cfg.h" #include "main.h" #include "gd32e230x_conf.h" #include "string.h" #include "Timer.h" //#define USR_LED_RCU RCU_GPIOB //#define USR_LED_IO GPIOB //#define USR_LED GPIO_PIN_11 uint8_t programe_erase_flag = 0; uint8_t programe_write_complete_flag = 0; uint8_t meta_erase_flag = 0; uint8_t meta_write_complete_flag = 0; uint8_t get_head_over_flag = 0; get_md_msg _msg = {0}; static uint32_t start_addr = 0x00000000; uint32_t my_addr = 0; static uint32_t erase_size = 0; uint16_t CurrentAddr = 0; uint32_t operation_cmd_cnt = 0; uint8_t flash_flag = 0; MD_DATA Md_Data[Mb_Wcmd_Width] = {0}; META_DATA_S meta_data = {0}; uint8_t read_meta_data[100] = {0}; g_MD_Data g_md_data={ .count = Mb_Wcmd_Width, .data = {0}, }; g_MD_Data* get_md_data() { return &g_md_data; } void flash_erase_page(uint32_t addr) { fmc_unlock(); fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); fmc_page_erase(addr); fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); fmc_lock(); } void flash_write_meta(META_DATA_S *meta_data) { fmc_unlock(); uint32_t address = META_DATA; uint32_t *data = (uint32_t*)(meta_data); uint32_t data0 = 0; for(int i = 0; i < sizeof(META_DATA_S);i++) { data0 = *data; fmc_word_program(address,data0); data ++; fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); address +=4; } fmc_lock(); } user_code application = NULL; __IO uint32_t JumpAddress = NULL; void UserJumpToApplication(uint32_t addr) { /* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */ uint32_t JumpAddress = 0; if (((*(uint32_t*)addr)&0x2FFE0000)==0x20000000) { /* Jump to user application */ __disable_irq(); // del_md_timer(); // del_modbus_uart(); // delete_Timer14(); // DeInitKey(); SCB->VTOR = addr; //nvic_vector_table_set(NVIC_VECTTAB_FLASH,0x5400); JumpAddress = *(__IO uint32_t*) (addr + 4); application = (user_code)JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t*)(addr)); application(); } } void flash_get_meta(META_DATA_S *meta) { meta->operation_flag = *(uint32_t*)(UPGRADE_FLAG_ADDR); meta->partition = *(uint32_t*)(STARTUP_PARTATION); meta->errno = *(uint32_t*)(STARTUP_ERROR); meta->error_count = *(uint32_t*)(STARTUP_NUMBEAR); meta->rom_addr = *(uint32_t*)(STARTUP_ROM_ADDR); meta->recent_running_time = *(uint32_t*)(STARTUP_LAST_RUNNING_TIME); meta->running_app_version = *(uint32_t*)(STARTUP_APP_VERSION); meta->app1_version = *(uint32_t*)(APP1_VERSION); meta->app1_rom_addr = *(uint32_t*)(APP1_ROM_ADDR); meta->app1_partition = *(uint32_t*)(APP1_PARTATION); meta->app2_version = *(uint32_t*)(APP2_VERSION); meta->app2_rom_addr = *(uint32_t*)(APP2_ROM_ADDR); meta->app2_partition = *(uint32_t*)(APP2_PARTATION); } void flash_write_programe(uint32_t *addr,uint32_t* source,uint32_t lenth) { fmc_unlock(); uint32_t *data = source; uint32_t *address = addr; for(int i = 0; i < ((lenth % 4) == 0 ? (lenth/4):((lenth/4)+1));i++,*address += 4) { fmc_word_program(*address,*data++); fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); } *addr = *address; fmc_lock(); } uint16_t cnt = 0; uint8_t md_status = 0; void operation_Flash_data(Flash_Data *data) { if(!data) return; if(data->index == 0) { if(md_status == UPGRADE_STATUS_IDE) { if(strncmp((const char *)(data->recive),MODBUS_HEAD,strlen(MODBUS_HEAD)) == 0){ //memcpy(head_buffer,data->recive,data->lenth); int lenth = strlen(MODBUS_HEAD); memcpy(&_msg.magic,data->recive,lenth); _msg.size = (data->recive[lenth]) | (data->recive[lenth+1] << 8); _msg.patition = (data->recive[lenth+2]) | (data->recive[lenth+3] << 8) | (data->recive[lenth+4] << 16) | (data->recive[lenth+5] << 24); _msg.version = (data->recive[lenth+6]) | (data->recive[lenth+6] << 8) | (data->recive[lenth+8] << 16) | (data->recive[lenth+9] << 24); get_head_over_flag = 1; } } }else { if(md_status == UPGRADE_STATUS_WRITE_PROGRAME) { flash_write_programe(&my_addr,(uint32_t*)(data->recive),data->lenth); if(data->index < 0) { programe_write_complete_flag = 1; } } } } void ModBus_CMD(void) { if(g_md_data.data[operation_cmd_cnt].flag == 1) { uint32_t base_addr = g_md_data.data[operation_cmd_cnt].base_addr; //check data is or not header metadata; switch(base_addr) { case MD_WRITE_Addr: { operation_Flash_data(&g_md_data.data[operation_cmd_cnt].flash_Data); } break; default: break; } g_md_data.data[operation_cmd_cnt].flag = 0; operation_cmd_cnt++; if(operation_cmd_cnt >= Mb_Wcmd_Width) { operation_cmd_cnt = 0; } } } Upgrade upgrade = {0}; Upgrade *get_upgrade() { return &upgrade; } int main(void) { SystemInit(); //systick_config(); InitLED(); InitKey(); InitTimer(); CurrentAddr = ReadKeyValue(); eMBInit(MB_RTU, CurrentAddr, 0, 115200, MB_PAR_NONE); eMBEnable(); flash_get_meta(&meta_data); if(meta_data.operation_flag == 0x0) { if(meta_data.rom_addr == PROGRAME_APP1 || meta_data.rom_addr == PROGRAME_APP2) { if(meta_data.errno != NOERROR && meta_data.error_count >= MAX_ERROR_COUNT) { //check current version is last versions? if(meta_data.app1_version == meta_data.app2_version) { }else { uint32_t version_max = meta_data.app1_version > meta_data.app2_version ? meta_data.app1_version :meta_data.app2_version; uint32_t version_min = meta_data.app1_version < meta_data.app2_version ? meta_data.app1_version :meta_data.app2_version; if(version_max == ERROR_VERSION) { }else if(meta_data.running_app_version == version_max) { //swtich lower version to running flash_erase_page(META_DATA); if(version_max == meta_data.app2_version){ meta_data.partition = meta_data.app1_partition; meta_data.rom_addr = meta_data.app1_rom_addr; }else { meta_data.partition = meta_data.app2_partition; meta_data.rom_addr = meta_data.app2_rom_addr; } meta_data.running_app_version = version_min; meta_data.errno = 0; meta_data.error_count = 0; flash_write_meta(&meta_data); UserJumpToApplication(meta_data.rom_addr); }else { ;; } } }else { UserJumpToApplication(meta_data.rom_addr); // } } }else { //wait to upgrade } md_status = UPGRADE_STATUS_IDE; while(1) { eMBPoll(); if(flash_flag) { LEDFlicker2(); flash_flag = 0; } ModBus_CMD(); switch(md_status) { case UPGRADE_STATUS_IDE: { //get and jie xi meta_data if(get_head_over_flag) { //½âÎöMetaDataºÍ²Á³ýflash if(_msg.patition == ONE){ start_addr =PROGRAME_APP1; erase_size = PROGRAME_APP1_SIZE; md_status = UPGRADE_STATUS_ERASE_PROGRAME; }else if(_msg.patition == SECOND){ start_addr = PROGRAME_APP2; erase_size = PROGRAME_APP2_SIZE; md_status = UPGRADE_STATUS_ERASE_PROGRAME; }else{ md_status = UPGRADE_STATUS_IDE; get_head_over_flag = 0; } } } break; case UPGRADE_STATUS_ERASE_PROGRAME: { uint32_t data = *(uint32_t*)(PROGRAME_APP1); if(programe_erase_flag == 0) { my_addr = start_addr; for(uint32_t i = 0;i < (erase_size/PAGE_SIZE);i++) { flash_erase_page(my_addr); my_addr += PAGE_SIZE; } my_addr = start_addr; programe_erase_flag = 1; md_status = UPGRADE_STATUS_WRITE_PROGRAME; } } break; case UPGRADE_STATUS_WRITE_PROGRAME: { if(programe_write_complete_flag) { md_status = UPGRADE_STATUS_ERASE_META; } } break; case UPGRADE_STATUS_ERASE_META: { if(meta_erase_flag == 0) { meta_data.partition = _msg.patition; meta_data.running_app_version = _msg.version; meta_data.errno = 0; meta_data.error_count = 0; if(meta_data.partition == ONE){ meta_data.rom_addr =PROGRAME_APP1; meta_data.app1_partition = _msg.patition; meta_data.app1_rom_addr = PROGRAME_APP1; meta_data.app1_version = _msg.version; } else if(meta_data.partition == SECOND) { meta_data.rom_addr =PROGRAME_APP2; meta_data.app2_partition = _msg.patition; meta_data.app2_rom_addr = PROGRAME_APP2; meta_data.app2_version = _msg.version; }else { // errno md_status = UPGRADE_STATUS_IDE; get_head_over_flag = 0; break; } meta_data.operation_flag = 0; meta_data.recent_running_time = 0; md_status = UPGRADE_STATUS_WTITE_META; flash_erase_page(META_DATA); meta_erase_flag = 1; } } break; case UPGRADE_STATUS_WTITE_META: { if(meta_write_complete_flag == 0){ flash_write_meta(&meta_data); md_status = UPGRADE_STATUS_FINISH; meta_write_complete_flag = 1; } } break; case UPGRADE_STATUS_FINISH: { UserJumpToApplication(start_addr); md_status = UPGRADE_STATUS_IDE; meta_write_complete_flag = 0; // meta_erase_flag = 0; get_head_over_flag = 0; programe_erase_flag = 0; programe_write_complete_flag = 0; } break; default: break; } } return 0; }