/** * @brief This function does an erase of all user flash area * @param StartSector: start of user flash area * @retval 0: user flash area successfully erased * 1: error occurred */ uint32_t FLASH_If_Erase(uint32_t StartSector) { uint32_t UserStartSector; uint32_t SectorError; FLASH_EraseInitTypeDef pEraseInit; /* Unlock the Flash to enable the flash control register access *************/ FLASH_If_Init(); /* Get the sector where start the user flash area */ UserStartSector = GetSector(APPLICATION_ADDRESS); pEraseInit.TypeErase = TYPEERASE_SECTORS; pEraseInit.Sector = UserStartSector; pEraseInit.NbSectors = 6; pEraseInit.VoltageRange = VOLTAGE_RANGE_3; if (HAL_FLASHEx_Erase(&pEraseInit, &SectorError) != HAL_OK) { /* Error occurred while page erase */ return (1); } return (0); }
/******************************************************************************* * Function Name : MAL_Init * Description : Initializes the Media on the STM32 * Input : None * Output : None * Return : None *******************************************************************************/ uint16_t MAL_Init(void) { FLASH_If_Init(); /* Internal Flash */ #if defined(USE_STM3210B_EVAL) || defined(USE_STM3210E_EVAL) SPI_If_Init(); /* SPI Flash */ #endif /* USE_STM3210B_EVAL or USE_STM3210E_EVAL */ #ifdef USE_STM3210E_EVAL NOR_If_Init(); /* NOR Flash */ FSMC_NOR_ReadID(&NOR_ID); FSMC_NOR_ReturnToReadMode(); /* select the alternate descriptor following NOR ID */ if ((NOR_ID.Manufacturer_Code == 0x01)&&(NOR_ID.Device_Code2 == NOR_S29GL128)) { DFU_String_Descriptor[6].Descriptor = DFU_StringInterface2_3; } /* select the alternate descriptor following NOR ID */ if ((NOR_ID.Manufacturer_Code == 0x20)&&(NOR_ID.Device_Code2 == NOR_M29W128G)) { DFU_String_Descriptor[6].Descriptor = DFU_StringInterface2_2; } #endif /* USE_STM3210E_EVAL */ return MAL_OK; }
/**************************************************************************************** ** 函数名称: FlashParaUpdate ** 功能描述: 更新Flash 中保存的参数 ** 参 数: 无 ** 返 回 值: none ** 作 者: Sevent ** 日 期: 2013年08月27日 **--------------------------------------------------------------------------------------- ** 修 改 人: ** 日 期: **-------------------------------------------------------------------------------------- ****************************************************************************************/ void FlashParaUpdate(EAbox_st *configData) { uint32_t paraStartAddress, paraEndAddress; paraStartAddress = PARA_START_ADDRESS; paraEndAddress = PARA_END_ADDRESS; FLASH_If_Init(); FLASH_If_Erase(paraStartAddress, paraEndAddress); // 擦除16K 数据保存区; FLASH_If_Write(¶StartAddress, (u32 *)configData, sizeof(eabox_config_t)); FLASH_Lock(); }
void updateConfiguration(mxchipWNet_HA_st *configData) { uint32_t paraStartAddress, paraEndAddress; paraStartAddress = PARA_START_ADDRESS; paraEndAddress = PARA_END_ADDRESS; FLASH_If_Init(); FLASH_If_Erase(paraStartAddress, paraEndAddress); FLASH_If_Write(¶StartAddress, (u32 *)&configData->conf, sizeof(mxchipWNet_HA_config_st)); FLASH_Lock(); }
void updateConfig(config_t *pConfig) { uint32_t paraStartAddress, paraEndAddress; paraStartAddress = PARA_START_ADDRESS; paraEndAddress = PARA_END_ADDRESS; FLASH_If_Init(); FLASH_If_Erase(paraStartAddress, paraEndAddress); // 擦除16K 数据保存区; FLASH_If_Write(¶StartAddress, (u32 *)pConfig, sizeof(config_t)); FLASH_Lock(); }
/** * @brief Processes TFTP write request * @param to: pointer on the receive IP address * @param to_port: receive port number * @retval none */ static int IAP_tftp_process_write(struct udp_pcb *upcb, struct ip_addr *to, int to_port) { tftp_connection_args *args = NULL; /* This function is called from a callback, * therefore interrupts are disabled, * therefore we can use regular malloc */ args = mem_malloc(sizeof *args); if (!args) { udp_lcd_y += UPDATE_WORD_SIZE + UPDATE_ROW_DISTANCE; lcd_font24(udp_lcd_x,udp_lcd_y,COLOR_POINT,COLOR_BACK,"> ÒÔÌ«ÍøÉý¼¶³ö´íÁË¡£´íÎó´úÂ룺5",UPDATE_FONT); UDP_AddUpdateError(); // #ifdef USE_LCD // LCD_SetTextColor(Red); // LCD_DisplayStringLine(Line9, (uint8_t*)"Memory error"); // #endif IAP_tftp_cleanup_wr(upcb, args); return 0; } args->op = TFTP_WRQ; args->to_ip.addr = to->addr; args->to_port = to_port; /* the block # used as a positive response to a WRQ is _always_ 0!!! (see RFC1350) */ args->block = 0; args->tot_bytes = 0; /* set callback for receives on this UDP PCB (Protocol Control Block) */ udp_recv(upcb, IAP_wrq_recv_callback, args); total_count =0; /* init flash */ FLASH_If_Init(); /* erase user flash area */ FLASH_If_Erase(USER_FLASH_FIRST_PAGE_ADDRESS); Flash_Write_Address = USER_FLASH_FIRST_PAGE_ADDRESS; /* initiate the write transaction by sending the first ack */ IAP_tftp_send_ack_packet(upcb, to, to_port, args->block); lcd_font24(udp_lcd_x,udp_lcd_y,COLOR_POINT,COLOR_BACK,"> ÕýÔÚдÈëÎļþ...",UPDATE_FONT); udp_lcd_y += UPDATE_WORD_SIZE + UPDATE_ROW_DISTANCE; // #ifdef USE_LCD // LCD_DisplayStringLine(Line8, (uint8_t*)"State: Programming.."); // #endif return 0; }
void restoreConfiguration(void) { EAbox_st EAboxInit; uint32_t paraStartAddress, paraEndAddress; paraStartAddress = PARA_START_ADDRESS; paraEndAddress = PARA_END_ADDRESS; memset(&EAboxInit, 0x0, sizeof(EAbox_st)); EAboxInit.conf.magicNumber = MAGIC_FLAG; FLASH_If_Init(); FLASH_If_Erase(paraStartAddress, paraEndAddress); // 擦除16K 数据保存区; FLASH_If_Write(¶StartAddress, (void *)&EAboxInit, sizeof(eabox_config_t)); FLASH_Lock(); }
//----- functions ----- void sampleMemory_init() { FLASH_If_Init(); //disable write protection if enabled if(FLASH_If_GetWriteProtectionStatus()) { FLASH_If_DisableWriteProtection(); } #if USE_SD_CARD sdManager_init(); #endif }
uint8 program_move(uint16 crc) { uint16 app_crc; uint16 cmp = 2; int t = 0; uint32_t addr_src = APP_ERCODE_ADDRESS; uint32_t addr_dst = APPLICATION_ADDRESS; FLASH_If_Init(); FLASH_If_Erase(APP_ERCODE_ADDRESS); FLASH_If_Write((__IO uint32_t* )&addr_dst, (uint32_t*)addr_src ,(0x400/4*29)); FLASH_Lock(); app_crc = cal_crc16((uint8*)APPLICATION_ADDRESS, 0x400*29); if(crc == app_crc) return 0; return 1; }
/** * @brief Main program * @param None * @retval None */ int main(void) { /* STM32F103xG HAL library initialization: - Configure the Flash prefetch - Systick timer is configured by default as source of time base, but user can eventually implement his proper time base source (a general purpose timer for example or other time source), keeping in mind that Time base duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and handled in milliseconds basis. - Set NVIC Group Priority to 4 - Low Level Initialization */ HAL_Init(); /* Configure the system clock to 72 MHz */ SystemClock_Config(); /* Initialize Key Button mounted on STM3210E-EVAL RevD board */ BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_GPIO); /* Test if Key push-button on STM3210E-EVAL RevD Board is pressed */ if (BSP_PB_GetState(BUTTON_KEY) == GPIO_PIN_RESET) { /* Initialise Flash */ FLASH_If_Init(); /* Execute the IAP driver in order to reprogram the Flash */ IAP_Init(); /* Display main menu */ Main_Menu (); } /* Keep the user application running */ else { /* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */ if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000) { /* Jump to user application */ JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4); JumpToApplication = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS); JumpToApplication(); } } while (1) {} }
void restoreConfig(void) { config_t config; net_para_st netPara; uint32_t paraStartAddress, paraEndAddress; paraStartAddress = PARA_START_ADDRESS; paraEndAddress = PARA_END_ADDRESS; getNetPara(&netPara,Station); memset(&config, 0x0, sizeof(config_t)); config.magicNumber = MAGIC_FLAG; sprintf((char*)config.wifi_ssid , "MXCHIP_%s", netPara.mac+6); sprintf((char*)config.wifi_key , ""); FLASH_If_Init(); FLASH_If_Erase(paraStartAddress, paraEndAddress); // 擦除16K 数据保存区; FLASH_If_Write(¶StartAddress, (void *)&config, sizeof(config_t)); FLASH_Lock(); }
/** * @brief Processes TFTP write request * @param to: pointer on the receive IP address * @param to_port: receive port number * @retval None */ static int IAP_tftp_process_write(struct udp_pcb *upcb, struct ip_addr *to, int to_port) { tftp_connection_args *args = NULL; /* This function is called from a callback, * therefore interrupts are disabled, * therefore we can use regular malloc */ args = mem_malloc(sizeof *args); if (!args) { #ifdef USE_LCD LCD_ErrLog("Memory error \n"); #endif IAP_tftp_cleanup_wr(upcb, args); return 0; } args->op = TFTP_WRQ; args->to_ip.addr = to->addr; args->to_port = to_port; /* the block # used as a positive response to a WRQ is _always_ 0!!! (see RFC1350) */ args->block = 0; args->tot_bytes = 0; /* set callback for receives on this UDP PCB (Protocol Control Block) */ udp_recv(upcb, IAP_wrq_recv_callback, args); total_count =0; /* init flash */ FLASH_If_Init(); /* erase user flash area */ FLASH_If_Erase(USER_FLASH_FIRST_PAGE_ADDRESS); Flash_Write_Address = USER_FLASH_FIRST_PAGE_ADDRESS; /* initiate the write transaction by sending the first ack */ IAP_tftp_send_ack_packet(upcb, to, to_port, args->block); #ifdef USE_LCD LCD_UsrLog(" State: Programming... \n"); #endif return 0; }
void restoreConfiguration(void) { mxchipWNet_HA_st mxchipWNet_HA_Init; uint32_t paraStartAddress, paraEndAddress; paraStartAddress = PARA_START_ADDRESS; paraEndAddress = PARA_END_ADDRESS; memset(&mxchipWNet_HA_Init, 0x0, sizeof(mxchipWNet_HA_st)); mxchipWNet_HA_Init.conf.magicNumber = MAGIC_FLAG; mxchipWNet_HA_Init.conf.versionNumber = CONFIGURATION_VERSION; mxchipWNet_HA_Init.conf.dhcp_enable = 1; strcpy((char*)mxchipWNet_HA_Init.conf.sta_ssid, DEFAULT_STA_SSID); strcpy((char*)mxchipWNet_HA_Init.conf.sta_key, DEFAULT_STA_KEY); strcpy((char*)mxchipWNet_HA_Init.conf.uap_ssid, DEFAULT_UAP_SSID); strcpy((char*)mxchipWNet_HA_Init.conf.uap_key, DEFAULT_UAP_KEY); strcpy((char*)mxchipWNet_HA_Init.conf.server_domain, DEFAULT_REMOTE_ADDR); mxchipWNet_HA_Init.conf.server_port = DEFAULT_REMOTE_PORT; FLASH_If_Init(); FLASH_If_Erase(paraStartAddress, paraEndAddress); FLASH_If_Write(¶StartAddress, (void *)&mxchipWNet_HA_Init, sizeof(mxchipWNet_HA_config_st)); FLASH_Lock(); }
/* * * Erase the new_fimware sector * */ void firmware_erase_new_firmware() { /* Enable flash writing */ FLASH_If_Init(); FLASH_If_Erase((uint32_t)NEW_FIRMWARE_FIRST_PAGE_ADDRESS, (uint32_t)NEW_FIRMWARE_LAST_PAGE_ADDRESS); }
static void get_update_post(int index, char *postdata, int len) { static const char endline[] = {'\r', '\n', '\r', '\n'}; static const char lengthstr[] = "Content-Length: "; static const char boundarystr[] = "boundary="; char *boundcp, *boundary, *p; char *read_buffer = postdata, *end_pos = NULL, *lengthpos; int read_buffer_size = len, time=5000; int bytes_received, read_len, content_len = 0, total_read; const char *resp; u32 addr = UPDATE_START_ADDRESS; /* Firmware update: OTA from webserver*/ setsockopt(index,0, SO_RCVTIMEO, &time, 4); /* Get the content length & boundary & begin of content data */ do { end_pos = (char*) memmem(read_buffer, read_buffer_size, endline, sizeof(endline)); if ( ( lengthpos = (char*) memmem( read_buffer, read_buffer_size, lengthstr, strlen( lengthstr )) ) != NULL ) { content_len = atoi(lengthpos + sizeof( lengthstr)-1); } if (( boundary = (char*) memmem( read_buffer, read_buffer_size, boundarystr, strlen(boundarystr) )) != NULL ) { boundary += strlen(boundarystr); p = boundary; while(*p != 0x0d) p++; *p++ = 0; // now, we have found out the boundary, copy out. boundcp = (char*)malloc(strlen(boundary)+1); if (boundcp != NULL) { strcpy(boundcp, boundary); } } if (end_pos == NULL) { read_buffer = httpRequest; bytes_received = recv(index, httpRequest, HTTP_DATA_MAX_LEN, 0 ); if ( bytes_received <= 0 ) { break; } else { total_read += bytes_received; read_buffer_size = bytes_received; } } } while ( end_pos == NULL ); if (boundcp == NULL || content_len == 0) { resp = systemResponseError; goto EXIT; } end_pos += sizeof(endline); read_buffer_size = read_buffer_size - (end_pos-read_buffer); content_len -= read_buffer_size; read_buffer = end_pos; /* Get the begin of file data and write to flash */ do { end_pos = (char*)memmem(read_buffer, read_buffer_size, endline, sizeof(endline)); if (end_pos == NULL) { read_buffer = httpRequest; bytes_received = recv(index, httpRequest, HTTP_DATA_MAX_LEN, 0 ); if ( bytes_received <= 0 ) { break; } else { content_len -= bytes_received; read_buffer_size = bytes_received; if (content_len <= 0) break; } } } while ( end_pos == NULL ); if (end_pos == NULL) { resp = systemResponseError; goto EXIT; } SetTimer(6000, delay_reload); // whether success or not, need reload system to use bootload erase NEW Image flash. FLASH_If_Init(); end_pos += sizeof(endline); read_buffer_size = read_buffer_size - (end_pos-read_buffer); if (read_buffer_size > 0) { FLASH_If_Write(&addr, (void *)end_pos, read_buffer_size); } content_len -= strlen(boundcp) - 4; // last string is '--'+boudnary+'--' /* Recv file and write to flash, if it's last package, find the end of file to write */ while(content_len > 0) { if (content_len > HTTP_DATA_MAX_LEN) read_len = HTTP_DATA_MAX_LEN; else read_len = content_len; bytes_received = recv(index, httpRequest, read_len, 0 ); if ( bytes_received <= 0 ) { break; } FLASH_If_Write(&addr, (void *)httpRequest, bytes_received); content_len -= bytes_received; } if (content_len == 0) { memset(&configParas, 0, sizeof(boot_table_t)); configParas.bootTable.length = addr - UPDATE_START_ADDRESS; configParas.bootTable.start_address = UPDATE_START_ADDRESS; configParas.bootTable.type = 'A'; configParas.bootTable.upgrade_type = 'U'; updateConfig(&configParas); resp = systemResponseSucc; } else resp = systemResponseError; EXIT: FLASH_Lock(); sprintf(httpRequest, HTTPSaveResponse, strlen(resp), resp); send_http_data(index, httpRequest, strlen(httpRequest)); }
/******************************************************************************* * Function Name : MAL_Init * Description : Initializes the Media on the STM32 * Input : None * Output : None * Return : None *******************************************************************************/ uint16_t MAL_Init(void) { FLASH_If_Init(); /* Internal Flash */ return MAL_OK; }
void updateProgram(void) { int clear = 0; int cmdByte, i, temp; FLASH_EraseResult result; uint32_t addr, maxAddr = 0; uint16_t endSector = 0xFFFF; _ee_getReserved(_AI_EE_RES_ADDR_MAX_SECTOR, &endSector); if (endSector > APPLICATION_END_SECTOR || !IS_FLASH_SECTOR(endSector)) endSector = APPLICATION_END_SECTOR; lcd_clear(); lcd_printf("Aithon Board\nProgramming..."); // Unlock the Flash Program Erase controller FLASH_If_Init(); while (TRUE) { led_toggle(0); cmdByte = getByte(); debugPrintCmd(cmdByte); switch (cmdByte) { case SYNC: // sync flushInterface(); sendResponse(SYNC, ACK); break; case ERASE_FLASH_START: if (FLASH_If_Erase_Start() == FLASH_ERASE_IN_PROGRESS) sendResponse(ERASE_FLASH_START, ACK); else sendResponse(ERASE_FLASH_START, NACK); break; case ERASE_FLASH_STATUS: result = FLASH_If_Erase_Status(endSector); if (result == FLASH_ERASE_COMPLETE) sendResponse(ERASE_FLASH_STATUS, ACK); else if (result == FLASH_ERASE_IN_PROGRESS) sendResponse(ERASE_FLASH_STATUS, BUSY); else sendResponse(ERASE_FLASH_STATUS, NACK); break; case SET_ADDR: // Read in the address, MSB first. addr = 0; for (i = 0; i < 4; i++) { if ((temp = getByte()) == Q_TIMEOUT) break; addr |= (((uint8_t) temp) & 0xFF) << (i * 8); } // Check for errors. if (temp == Q_TIMEOUT) sendResponse(SET_ADDR, NACK); else { sendResponse(SET_ADDR, ACK); // We'll get relative addresses, so add the start address. addr += APPLICATION_START_ADDRESS; } break; case CHECK_ADDR: // Get the checksum temp = getByte(); if (temp == Q_TIMEOUT) sendResponse(CHECK_ADDR, NACK); else { // Subtract the start address before calculating the checksum addr -= APPLICATION_START_ADDRESS; if (temp == calcChecksum((uint8_t *)&addr, 4)) sendResponse(CHECK_ADDR, ACK); else sendResponse(CHECK_ADDR, NACK); addr += APPLICATION_START_ADDRESS; } break; case FILL_BUFFER: for (i = 0; i < PACKET_LEN; i++) { if ((temp = getByte()) == Q_TIMEOUT) break; _buffer[i] = (uint8_t) (temp & 0xFF); } if (temp == Q_TIMEOUT) sendResponse(FILL_BUFFER, NACK); else sendResponse(FILL_BUFFER, ACK); break; case CHECK_BUFFER: // Get the checksum temp = getByte(); if (temp != Q_TIMEOUT && temp == calcChecksum(_buffer, PACKET_LEN)) sendResponse(CHECK_BUFFER, ACK); else sendResponse(CHECK_BUFFER, NACK); break; case COMMIT_BUFFER: maxAddr = addr + PACKET_LEN - 1; if (FLASH_If_Write((__IO uint32_t *)&addr, (uint32_t *)_buffer, PACKET_LEN/4)) sendResponse(COMMIT_BUFFER, NACK); else sendResponse(COMMIT_BUFFER, ACK); break; case START_PROGRAM: sendResponse(START_PROGRAM, ACK); flushInterface(); _ee_putReserved(_AI_EE_RES_ADDR_MAX_SECTOR, FLASH_Addr_To_Sector(maxAddr)); delayS(1); startProgram(); // ...should never get here return; case Q_TIMEOUT: default: if (clear == 0) { lcd_clear(); clear = 1; } lcd_printf ("0%x ", cmdByte); break; } } }
void firmware_erase_firmware_temp() { /* Enable flash writing */ FLASH_If_Init(); FLASH_If_Erase((uint32_t)FIRMWARE_TEMP_FIRST_PAGE_ADDRESS, (uint32_t)FIRMWARE_TEMP_LAST_PAGE_ADDRESS); }