int OTAClass::set_system_data(uint32_t address, uint32_t value) { flash_t flash; uint32_t i, data; flash_write_word(&flash, FLASH_SYSTEM_DATA_ADDR + address, value); flash_read_word(&flash, FLASH_SYSTEM_DATA_ADDR + address, &data); if (value != data) { //erase backup sector flash_erase_sector(&flash, FLASH_RESERVED_DATA_BASE); //backup system data to backup sector for(i = 0; i < 0x1000; i+= 4){ flash_read_word(&flash, FLASH_SYSTEM_DATA_ADDR + i, &data); flash_write_word(&flash, FLASH_RESERVED_DATA_BASE + i,data); } //erase system data flash_erase_sector(&flash, FLASH_SYSTEM_DATA_ADDR); //write data back to system data for(i = 0; i < 0x1000; i+= 4){ flash_read_word(&flash, FLASH_RESERVED_DATA_BASE + i, &data); if(i == address) data = value; flash_write_word(&flash, FLASH_SYSTEM_DATA_ADDR + i,data); } //erase backup sector flash_erase_sector(&flash, FLASH_RESERVED_DATA_BASE); } }
int write_ota_addr_to_system_data(flash_t *flash, uint32_t ota_addr) { uint32_t data, i = 0; //Get upgraded image 2 addr from offset flash_read_word(flash, OFFSET_DATA, &data); printf("\n\r[%s] data 0x%x ota_addr 0x%x", __FUNCTION__, data, ota_addr); if(data == ~0x0){ flash_write_word(flash, OFFSET_DATA, ota_addr); }else{ //erase backup sector flash_erase_sector(flash, BACKUP_SECTOR); //backup system data to backup sector for(i = 0; i < 0x1000; i+= 4){ flash_read_word(flash, OFFSET_DATA + i, &data); if(i == 0) data = ota_addr; flash_write_word(flash, BACKUP_SECTOR + i,data); } //erase system data flash_erase_sector(flash, OFFSET_DATA); //write data back to system data for(i = 0; i < 0x1000; i+= 4){ flash_read_word(flash, BACKUP_SECTOR + i, &data); flash_write_word(flash, OFFSET_DATA + i,data); } //erase backup sector flash_erase_sector(flash, BACKUP_SECTOR); } return 0; }
static int amd_flash_write_cfibuffer(struct flash_info *info, unsigned long dest, const u8 *cp, int len) { flash_sect_t sector; int cnt; void *src = (void *)cp; void *dst = (void *)dest; cfiword_t cword; sector = find_sector (info, dest); flash_unlock_seq(info); flash_make_cmd (info, AMD_CMD_WRITE_TO_BUFFER, &cword); flash_write_word(info, cword, (void *)dest); if (bankwidth_is_1(info)) { cnt = len; flash_write_cmd(info, sector, 0, (u32)cnt - 1); while (cnt-- > 0) { flash_write8(flash_read8(src), dst); src += 1, dst += 1; } } else if (bankwidth_is_2(info)) { cnt = len >> 1; flash_write_cmd(info, sector, 0, (u32)cnt - 1); while (cnt-- > 0) { flash_write16(flash_read16(src), dst); src += 2, dst += 2; } } else if (bankwidth_is_4(info)) {
static int amd_flash_write_cfibuffer (struct flash_info *info, ulong dest, const uchar * cp, int len) { flash_sect_t sector; int cnt; int retcode; volatile cfiptr_t src; volatile cfiptr_t dst; cfiword_t cword; src.cp = (uchar *)cp; dst.cp = (uchar *) dest; sector = find_sector (info, dest); flash_unlock_seq(info); flash_make_cmd (info, AMD_CMD_WRITE_TO_BUFFER, &cword); flash_write_word(info, cword, (void *)dest); if (bankwidth_is_1(info)) { cnt = len; flash_write_cmd (info, sector, 0, (uchar) cnt - 1); while (cnt-- > 0) *dst.cp++ = *src.cp++; } else if (bankwidth_is_2(info)) { cnt = len >> 1; flash_write_cmd (info, sector, 0, (uchar) cnt - 1); while (cnt-- > 0) *dst.wp++ = *src.wp++; } else if (bankwidth_is_4(info)) {
int uartadapter_flashwrite(int flashadd, char *pbuf, int len) { int ret = 0; flash_t flash; if( len == 0){ ua_printf(UA_ERROR, "inpua error,data length should not be null!"); ret = -1; return ret; } else //as 8711am only canbe r/w in words.so make len is 4-bytes aligmented. len += 4 - ((len%4)==0 ? 4 : (len%4)); while(len){ if(flash_write_word(&flash, flashadd, *(unsigned int *)pbuf) !=1 ){ ua_printf(UA_ERROR, "write flash error!"); ret = -1; return ret; } len -= 4; pbuf += 4; flashadd += 4; } return ret; }
int OTAClass::sync_ota_addr() { flash_t flash; uint32_t ota_addr_in_flash; flash_read_word(&flash, FLASH_SYSTEM_DATA_ADDR, &ota_addr_in_flash); if (ota_addr_in_flash == ~0x0) { // No OTA address configuired in flash OTA_PRINTF("use default OTA address\r\n"); ota_addr = DEFAULT_OTA_ADDRESS; flash_write_word(&flash, FLASH_SYSTEM_DATA_ADDR, ota_addr); } else { ota_addr = ota_addr_in_flash; } }
char flash_write(short size, int offset, uint32 value){ switch(size){ case 8: flash_write_byte (offset, value); break; case 16: flash_write_halfword(offset, value); break; case 32: flash_write_word(offset, value); break; default: return -1; } return 0; }
void main(void) { flash_t flash; uint32_t val32_to_write = 0x13572468; uint32_t val32_to_read; uint32_t address = FLASH_APP_BASE; int result = 0; flash_read_word(&flash, address, &val32_to_read); flash_erase_sector(&flash, address); flash_write_word(&flash, address, val32_to_write); flash_read_word(&flash, address, &val32_to_read); DBG_8195A("Read Data 0x%x\n", val32_to_read); // verify result result = (val32_to_write == val32_to_read) ? 1 : 0; printf("\r\nResult is %s\r\n", (result) ? "success" : "fail"); for(;;); }
int OTAClass::beginLocal(uint16_t port, bool reboot_when_success) { int ret = -1; // variables for image processing flash_t flash; uint32_t img2_addr, img2_len, img3_addr, img3_len; uint32_t img_upper_bound; uint32_t checksum = 0; uint32_t signature1, signature2; // variables for network processing int server_socket = -1; int client_socket = -1; struct sockaddr_in localHost; struct sockaddr_in client_addr; int socket_error, socket_timeout; socklen_t optlen; // variables for OTA unsigned char *buf = NULL; int read_bytes = 0, processed_len; uint32_t file_info[3]; uint32_t ota_len; uint32_t ota_blk_size = 0; int i, n; do { sync_ota_addr(); get_image_info(&img2_addr, &img2_len, &img3_addr, &img3_len); img_upper_bound = img2_addr + 0x10 + img2_len; // image2 base + header + len if (img3_len > 0) { img_upper_bound += 0x10 + img3_len; // image 3 header + len } if ((ota_addr & 0xfff != 0) || (ota_addr == ~0x0) || (ota_addr < img_upper_bound)) { OTA_PRINTF("Invalid OTA address: %08X\r\n", ota_addr); break; } buf = (unsigned char *) malloc (BUFSIZE); if (buf == NULL) { OTA_PRINTF("Fail to allocate memory\r\n"); break; } server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (server_socket < 0) { OTA_PRINTF("Fail to create socket\r\n"); break; } memset(&localHost, 0, sizeof(localHost)); localHost.sin_family = AF_INET; localHost.sin_port = htons(port); localHost.sin_addr.s_addr = INADDR_ANY; if (lwip_bind(server_socket, (struct sockaddr *)&localHost, sizeof(localHost)) < 0) { OTA_PRINTF("Bind fail\r\n"); break; } if (lwip_listen(server_socket , 1) < 0) { OTA_PRINTF("Listen fail\r\n"); break; } OTA_PRINTF("Wait for client\r\n"); n = (int) sizeof( client_addr ); memset(&client_addr, 0, sizeof(client_addr)); client_socket = lwip_accept(server_socket, (struct sockaddr *) &client_addr, (socklen_t *)&n); OTA_PRINTF("Client connected. IP:%s port:%d\r\n\r\n", inet_ntoa(client_addr.sin_addr.s_addr), ntohs(client_addr.sin_port)); socket_timeout = DEFAULT_IMAGE_DOWNLOAD_TIMEOUT; lwip_setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO, &socket_timeout, sizeof(socket_timeout)); OTA_PRINTF("Read OTA info...\r\n"); read_bytes = read(client_socket, file_info, sizeof(file_info)); if (read_bytes < 0) { OTA_PRINTF("Fail to read OTA info\r\n"); break; } if (file_info[2] == 0) { OTA_PRINTF("OTA image len is 0\r\n"); break; } ota_len = file_info[2]; ota_blk_size = ((ota_len - 1) / 4096) + 1; for (i = 0; i < ota_blk_size; i++) { flash_erase_sector(&flash, ota_addr + i * 4096); } OTA_PRINTF("Start download\r\n"); // Now download OTA image processed_len = 0; while( processed_len < ota_len ) { memset(buf, 0, BUFSIZE); read_bytes = read(client_socket, buf, BUFSIZE); if (read_bytes < 0) { optlen = sizeof(socket_error); getsockopt(client_socket, SOL_SOCKET, SO_ERROR, &socket_error, &optlen); if (socket_error == EAGAIN) { // socket timeout } break; } if (flash_stream_write(&flash, ota_addr + processed_len, read_bytes, buf) < 0) { OTA_PRINTF("Write sector fail\r\n"); break; } processed_len += read_bytes; } if (processed_len != ota_len) { OTA_PRINTF("Download fail\r\n"); break; } // Read OTA image from flash and calculate checksum checksum = processed_len = 0; while ( processed_len < ota_len ) { n = (processed_len + BUFSIZE < ota_len) ? BUFSIZE : (ota_len - processed_len); flash_stream_read(&flash, ota_addr + processed_len, n, buf); for (i=0; i<n; i++) checksum += (buf[i] & 0xFF); processed_len += n; } if (checksum != file_info[0]) { OTA_PRINTF("Bad checksum:%d expected:%d\r\n", checksum, file_info[0]); break; } // Put signature for OTA image flash_write_word(&flash, ota_addr + 8, 0x35393138); flash_write_word(&flash, ota_addr + 12, 0x31313738); flash_read_word(&flash, ota_addr + 8, &signature1); flash_read_word(&flash, ota_addr + 12, &signature2); if (signature1 != 0x35393138 || signature2 != 0x31313738) { OTA_PRINTF("Put signature fail\r\n"); break; } // Mark image 2 as old image flash_write_word(&flash, img2_addr + 8, 0x35393130); ret = 0; OTA_PRINTF("OTA success\r\n"); } while (0); if (buf != NULL) { free(buf); } if (server_socket >= 0) { close(server_socket); } if (client_socket >= 0) { close(client_socket); } if (ret < 0) { OTA_PRINTF("OTA fail\r\n"); } else { if (reboot_when_success) { sys_reset(); } } return ret; }
void main(void) { byte test; byte manuf_id; word device_id; byte far *str; word test2,i; dword sec_size=0; long count=0; printf("Beginning test.....\n\n"); /* First, poke around the memory map to see what kind of flash is installed in the socket...assume a DL800B */ /* The purpose of init_flash is to perform any system memory mapping required, and to set up pointers to those region(s). init_flash() also selects the proper sector organization table defined in flash.c Note: init_flash() will need to be provided by users of the flash.c routines */ if(!init_flash(AM29DL800B)) { exit(1); } /* Verify the manufacturer code is indeed 0x01 for AMD */ manuf_id = flash_get_manuf_code(0); switch(manuf_id) { case AMDPART: printf("AMD Flash found in socket...\n"); break; default: printf("Non AMD part found in socket...exiting.\n"); exit(1); break; } /* Poll the device id so that the proper sector layout table is used for the device in the socket */ printf("Polling part for Device ID..."); /* Retrieve the device ID for this AMD flash part. All device id's are stored in flash.h */ device_id = flash_get_device_id(0); switch(device_id) { case ID_AM29DL800T: printf("found an Am29DL800T\n"); if(!init_flash(AM29DL800T)) exit(1); break; case ID_AM29DL800B: printf("found an Am29DL800B\n"); if(!init_flash(AM29DL800B)) exit(1); break; case ID_AM29LV800T: printf("found an Am29LV800T\n"); if(!init_flash(AM29LV800T)) exit(1); break; case ID_AM29LV800B: printf("found an Am29LV800B\n"); if(!init_flash(AM29LV800B)) exit(1); break; case ID_AM29LV160B: printf( "found an Am29LV160B\n"); if(!init_flash(AM29LV160B)) exit(1); break; case ID_AM29LV400B: printf( "found an Am29LV400B\n"); if(!init_flash(AM29LV400B)) exit(1); break; default: printf("error reading Device ID...exiting.\n"); exit(1); break; } randomize(); /* flash_get_status uses DQ7, DQ5, and DQ2 polling to get the status of the flash. All status codes are defined in flash.h Also note that for the DL parts, status is bank dependent */ printf("Checking current flash status...flash is "); test = flash_get_status(0); switch(test) { case STATUS_READY: printf("[Ready]\n");break; case STATUS_BUSY: printf("[Busy]\n");break; case STATUS_ERSUSP: printf("[Erase Suspended]\n");break; case STATUS_TIMEOUT: printf("[Timed Out]\n");break; default: printf("Error!\n"); exit(1);break; } printf("Performing API tests...\n\n"); /* flash_sector_erase_int() is the function which erases a single sector. It is different from flash_sector_erase() in that it 'interrupts' execution of the program until the erase is completed. For erasing a sector without pausing use flash_sector_erase(). */ flash_reset(); /* Quick safe check */ printf("Erasing sector 8..."); flash_sector_erase_int(8); printf("done.\n"); printf("Verifying erase..."); flash_get_sector_size(8, &sec_size); /* Get # of byte */ /* A simple test which reads every word from the flash, and checks to see if every word contains the data 0xFFFF, which indicates an erased word. */ for (count=0 ; count < (sec_size/2); count++) { if(count%2048 == 0) printf("."); /*print out some dots to show the program hasn't frozen */ if (flash_read_word(8,count) != 0xFFFF) { printf("erase not completed sucessfully!\n"); exit(1); } } printf("erase successful.\n"); /* flash_write_word() takes word data and programs it to the flash at the indicated offset. Note that this data must be *word aligned*, or else programming errors can result. It is also good to check the word for 0xFFFF data before programming. */ printf("Writing a single word [0xABCD]\n"); flash_write_word(8,0,0xABCD); /* flash_read_word() returns a single word of data at the specified sector/offset . Must also be word aligned */ printf("After write(0xABCD): %4x\n", flash_read_word(8,0)); str = (byte far *) calloc(0x7FFF, sizeof(byte)); /* Randomize the string with random ASCII characters */ for(i=0; i<0x7FFF; i++) { str[i] = (byte) (41 + (rand() % 26)); } printf("Erasing sector 9..."); flash_sector_erase_int(9); printf("done.\n"); /* flash_write_string() is a function to program bulk data from a C buffer. It is a bit faster than looping techniques using flash_write_word() because function overhead is eliminated. */ printf("Writing 32 kbyte string..."); flash_write_string(9,0,str,0x7FFE); printf("done.\n\n"); printf("Testing erase suspend\n"); printf("Beginning erase...\n"); /* This is an example of flash_sector_erase(). Note that the program will simply issue the command, and execution will continue while the flash is erasing. */ flash_sector_erase(10); /* flash_erase_suspend will suspend an erase in progress. The application can then do any reading of data from that sector, or another sector. */ printf("Suspending erase..."); flash_erase_suspend(10); printf("done.\n"); /* The current flash status should now be STATUS_ERSUSP */ printf("Checking current flash status...flash is "); test = flash_get_status(10); switch(test) { case STATUS_READY: printf("[Ready]\n");break; case STATUS_BUSY: printf("[Busy]\n");break; case STATUS_ERSUSP: printf("[Erase Suspended]\n");break; case STATUS_TIMEOUT: printf("[Timed Out]\n");break; default: printf("Error!\n"); exit(1);break; } /* Now we can resume the erase previously suspended */ printf("Resuming erase after status check.."); flash_erase_resume(10); printf("done.\n"); /* Now for a test of unlock bypass mode */ /* Unlock bypass allows for faster programming of flash data in that the number of required bus cycles is cut in half. The most benefit can be realized when programming large amounts of data using flash_write_string_ub() */ printf("Entering unlock bypass mode...\n"); flash_sector_erase_int(11); flash_ub(11); /* Enter unlock bypass mode */ printf("Programming a string in unlock bypass mode.."); flash_write_string_ub(11,0,str,0x7FFE); printf("done.\n"); printf("Exiting unlock bypass mode..\n"); flash_reset_ub(); flash_reset(); /* Last thing is a quick loop through all the sectors to check for sector protection. */ printf("\nVerifying sector protection...\n"); flash_get_numsectors(&test2); printf("This device contains %3i sectors: \n", test2); for(i=0; i < test2; i++) { test = flash_sector_protect_verify(i); flash_get_sector_size(i, &size); printf("Verify sector #%2i, size [%-5li]: ", i, size); if (test == 0x01) printf("sector is protected[%2i].\n", test); else printf("sector is not protected[%2i].\n", test); flash_reset(); } printf("Test drive done!\n"); free(str); exit(0); }
void main(void) { flash_t flash; uint32_t address = FLASH_APP_BASE; #if 1 uint32_t val32_to_write = 0x13572468; uint32_t val32_to_read; int loop = 0; int result = 0; for(loop = 0; loop < 10; loop++) { flash_read_word(&flash, address, &val32_to_read); DBG_8195A("Read Data 0x%x\n", val32_to_read); flash_erase_sector(&flash, address); flash_write_word(&flash, address, val32_to_write); flash_read_word(&flash, address, &val32_to_read); DBG_8195A("Read Data 0x%x\n", val32_to_read); // verify result result = (val32_to_write == val32_to_read) ? 1 : 0; //printf("\r\nResult is %s\r\n", (result) ? "success" : "fail"); DBG_8195A("\r\nResult is %s\r\n", (result) ? "success" : "fail"); result = 0; } #else int VERIFY_SIZE = 256; int SECTOR_SIZE = 16; uint8_t writedata[VERIFY_SIZE]; uint8_t readdata[VERIFY_SIZE]; uint8_t verifydata = 0; int loop = 0; int index = 0; int sectorindex = 0; int result = 0; int resultsector = 0; int testloop = 0; for(testloop = 0; testloop < 1; testloop++){ address = FLASH_APP_BASE; for(sectorindex = 0; sectorindex < 4080; sectorindex++){ result = 0; //address += SECTOR_SIZE; flash_erase_sector(&flash, address); //DBG_8195A("Address = %x \n", address); for(loop = 0; loop < SECTOR_SIZE; loop++){ for(index = 0; index < VERIFY_SIZE; index++) { writedata[index] = verifydata + index; } flash_stream_write(&flash, address, VERIFY_SIZE, &writedata); flash_stream_read(&flash, address, VERIFY_SIZE, &readdata); for(index = 0; index < VERIFY_SIZE; index++) { //DBG_8195A("Address = %x, Writedata = %x, Readdata = %x \n",address,writedata[index],readdata[index]); if(readdata[index] != writedata[index]){ DBG_8195A("Error: Loop = %d, Address = %x, Writedata = %x, Readdata = %x \n",testloop,address,writedata[index],readdata[index]); } else{ result++; //DBG_8195A(ANSI_COLOR_BLUE"Correct: Loop = %d, Address = %x, Writedata = %x, Readdata = %x \n"ANSI_COLOR_RESET,testloop,address,writedata[index],readdata[index]); } } address += VERIFY_SIZE; } if(result == VERIFY_SIZE * SECTOR_SIZE){ //DBG_8195A("Sector %d Success \n", sectorindex); resultsector++; } } if(resultsector == 4079){ DBG_8195A("Test Loop %d Success \n", testloop); } resultsector = 0; verifydata++; } //DBG_8195A("%d Sector Success \n", resultsector); DBG_8195A("Test Done"); #endif for(;;); }
int StoreApInfo() { flash_t flash; rtw_wifi_config_t wifi_config; uint32_t address; uint32_t data,i = 0; address = DATA_SECTOR; wifi_config.boot_mode = 0x77665502; memcpy(wifi_config.ssid, wifi_setting.ssid, strlen((char*)wifi_setting.ssid)); wifi_config.ssid_len = strlen((char*)wifi_setting.ssid); wifi_config.security_type = wifi_setting.security_type; if(wifi_setting.security_type !=0) wifi_config.security_type = 1; else wifi_config.security_type = 0; memcpy(wifi_config.password, wifi_setting.password, strlen((char*)wifi_setting.password)); wifi_config.password_len= strlen((char*)wifi_setting.password); wifi_config.channel = wifi_setting.channel; printf("\n\rWritting boot mode 0x77665502 and Wi-Fi setting to flash ..."); //printf("\n\r &wifi_config = 0x%x",&wifi_config); flash_read_word(&flash,address,&data); if(data == ~0x0) flash_stream_write(&flash, address,sizeof(rtw_wifi_config_t), (uint8_t *)&wifi_config); else{ //flash_EraseSector(sector_nb); flash_erase_sector(&flash,BACKUP_SECTOR); for(i = 0; i < 0x1000; i+= 4){ flash_read_word(&flash, DATA_SECTOR + i, &data); if(i < sizeof(rtw_wifi_config_t)) { memcpy(&data,(char *)(&wifi_config) + i,4); //printf("\n\r Wifi_config + %d = 0x%x",i,(void *)(&wifi_config + i)); //printf("\n\r Data = %d",data); } flash_write_word(&flash, BACKUP_SECTOR + i,data); } flash_read_word(&flash,BACKUP_SECTOR + 68,&data); //printf("\n\r Base + BACKUP_SECTOR + 68 wifi channel = %d",data); //erase system data flash_erase_sector(&flash, DATA_SECTOR); //write data back to system data for(i = 0; i < 0x1000; i+= 4){ flash_read_word(&flash, BACKUP_SECTOR + i, &data); flash_write_word(&flash, DATA_SECTOR + i,data); } //erase backup sector flash_erase_sector(&flash, BACKUP_SECTOR); } //flash_Wrtie(address, (char *)&wifi_config, sizeof(rtw_wifi_config_t)); //flash_stream_write(&flash, address,sizeof(rtw_wifi_config_t), (uint8_t *)&wifi_config); //flash_stream_read(&flash, address, sizeof(rtw_wifi_config_t),data); //flash_stream_read(&flash, address, sizeof(rtw_wifi_config_t),data); //printf("\n\r Base + 0x000FF000 +4 wifi config = %s",data[4]); //printf("\n\r Base + 0x000FF000 +71 wifi channel = %d",data[71]); return 0; }
/* * storage_commit() - Write content of configuration in shadow memory to * storage partion in flash * * INPUT * none * OUTPUT * none */ void storage_commit(void) { uint32_t shadow_ram_crc32, shadow_flash_crc32, retries; memcpy((void *)&shadow_config, STORAGE_MAGIC_STR, STORAGE_MAGIC_LEN); for(retries = 0; retries < STORAGE_RETRIES; retries++) { /* Capture CRC for verification at restore */ shadow_ram_crc32 = calc_crc32((uint32_t *)&shadow_config, sizeof(shadow_config) / sizeof(uint32_t)); if(shadow_ram_crc32 == 0) { continue; /* Retry */ } /* Make sure flash is in good state before proceeding */ if(!flash_chk_status()) { flash_clear_status_flags(); continue; /* Retry */ } /* Make sure storage sector is valid before proceeding */ if(storage_location < FLASH_STORAGE1 && storage_location > FLASH_STORAGE3) { /* Let it exhaust the retries and error out */ continue; } flash_unlock(); flash_erase_word(storage_location); wear_leveling_shift(); flash_erase_word(storage_location); /* Load storage data first before loading storage magic */ if(flash_write_word(storage_location, STORAGE_MAGIC_LEN, sizeof(shadow_config) - STORAGE_MAGIC_LEN, (uint8_t *)&shadow_config + STORAGE_MAGIC_LEN)) { if(!flash_write_word(storage_location, 0, STORAGE_MAGIC_LEN, (uint8_t *)&shadow_config)) { continue; /* Retry */ } } else { continue; /* Retry */ } /* Flash write completed successfully. Verify CRC */ shadow_flash_crc32 = calc_crc32((uint32_t *)flash_write_helper( storage_location), sizeof(shadow_config) / sizeof(uint32_t)); if(shadow_flash_crc32 == shadow_ram_crc32) { /* Commit successful, break to exit */ break; } else { continue; /* Retry */ } } flash_lock(); if(retries >= STORAGE_RETRIES) { layout_warning_static("Error Detected. Reboot Device!"); system_halt(); } }
static void update_ota_local_task(void *param) { int server_socket; struct sockaddr_in server_addr; unsigned char *buf; union { uint32_t u; unsigned char c[4]; } file_checksum; int read_bytes = 0, size = 0, i = 0; update_cfg_local_t *cfg = (update_cfg_local_t *)param; uint32_t address, checksum = 0; flash_t flash; uint32_t NewImg2BlkSize = 0, NewImg2Len = 0, NewImg2Addr = 0, file_info[3]; uint32_t Img2Len = 0; int ret = -1 ; //uint8_t signature[8] = {0x38,0x31,0x39,0x35,0x38,0x37,0x31,0x31}; uint32_t IMAGE_x = 0, ImgxLen = 0, ImgxAddr = 0; #if WRITE_OTA_ADDR uint32_t ota_addr = 0x80000; #endif #if CONFIG_CUSTOM_SIGNATURE char custom_sig[32] = "Customer Signature-modelxxx"; uint32_t read_custom_sig[8]; #endif printf("\n\r[%s] Update task start", __FUNCTION__); buf = update_malloc(BUF_SIZE); if(!buf){ printf("\n\r[%s] Alloc buffer failed", __FUNCTION__); goto update_ota_exit; } // Connect socket server_socket = socket(AF_INET, SOCK_STREAM, 0); if(server_socket < 0){ printf("\n\r[%s] Create socket failed", __FUNCTION__); goto update_ota_exit; } server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = cfg->ip_addr; server_addr.sin_port = cfg->port; if(connect(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1){ printf("\n\r[%s] socket connect failed", __FUNCTION__); goto update_ota_exit; } DBG_INFO_MSG_OFF(_DBG_SPI_FLASH_); #if 1 // The upgraded image2 pointer must 4K aligned and should not overlap with Default Image2 flash_read_word(&flash, IMAGE_2, &Img2Len); IMAGE_x = IMAGE_2 + Img2Len + 0x10; flash_read_word(&flash, IMAGE_x, &ImgxLen); flash_read_word(&flash, IMAGE_x+4, &ImgxAddr); if(ImgxAddr==0x30000000){ printf("\n\r[%s] IMAGE_3 0x%x Img3Len 0x%x", __FUNCTION__, IMAGE_x, ImgxLen); }else{ printf("\n\r[%s] no IMAGE_3", __FUNCTION__); // no image3 IMAGE_x = IMAGE_2; ImgxLen = Img2Len; } #if WRITE_OTA_ADDR if((ota_addr > IMAGE_x) && ((ota_addr < (IMAGE_x+ImgxLen))) || (ota_addr < IMAGE_x) || ((ota_addr & 0xfff) != 0)|| (ota_addr == ~0x0)){ printf("\n\r[%s] illegal ota addr 0x%x", __FUNCTION__, ota_addr); goto update_ota_exit; }else write_ota_addr_to_system_data( &flash, ota_addr); #endif //Get upgraded image 2 addr from offset flash_read_word(&flash, OFFSET_DATA, &NewImg2Addr); if((NewImg2Addr > IMAGE_x) && ((NewImg2Addr < (IMAGE_x+ImgxLen))) || (NewImg2Addr < IMAGE_x) || ((NewImg2Addr & 0xfff) != 0)|| (NewImg2Addr == ~0x0)){ printf("\n\r[%s] Invalid OTA Address 0x%x", __FUNCTION__, NewImg2Addr); goto update_ota_exit; } #else //For test, hard code addr NewImg2Addr = 0x80000; #endif //Clear file_info memset(file_info, 0, sizeof(file_info)); if(file_info[0] == 0){ printf("\n\r[%s] Read info first", __FUNCTION__); read_bytes = read(server_socket, file_info, sizeof(file_info)); // !X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X // !W checksum !W padding 0 !W file size !W // !X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X printf("\n\r[%s] info %d bytes", __FUNCTION__, read_bytes); printf("\n\r[%s] tx chechsum 0x%x, file size 0x%x", __FUNCTION__, file_info[0],file_info[2]); if(file_info[2] == 0){ printf("\n\r[%s] No checksum and file size", __FUNCTION__); goto update_ota_exit; } } #if SWAP_UPDATE uint32_t SigImage0,SigImage1; uint32_t Part1Addr=0xFFFFFFFF, Part2Addr=0xFFFFFFFF, ATSCAddr=0xFFFFFFFF; uint32_t OldImg2Addr; flash_read_word(&flash, 0x18, &Part1Addr); Part1Addr = (Part1Addr&0xFFFF)*1024; // first partition Part2Addr = NewImg2Addr; // read Part1/Part2 signature flash_read_word(&flash, Part1Addr+8, &SigImage0); flash_read_word(&flash, Part1Addr+12, &SigImage1); printf("\n\r[%s] Part1 Sig %x", __FUNCTION__, SigImage0); if(SigImage0==0x30303030 && SigImage1==0x30303030) ATSCAddr = Part1Addr; // ATSC signature else if(SigImage0==0x35393138 && SigImage1==0x31313738) OldImg2Addr = Part1Addr; // newer version, change to older version else NewImg2Addr = Part1Addr; // update to older version flash_read_word(&flash, Part2Addr+8, &SigImage0); flash_read_word(&flash, Part2Addr+12, &SigImage1); printf("\n\r[%s] Part2 Sig %x", __FUNCTION__, SigImage0); if(SigImage0==0x30303030 && SigImage1==0x30303030) ATSCAddr = Part2Addr; // ATSC signature else if(SigImage0==0x35393138 && SigImage1==0x31313738) OldImg2Addr = Part2Addr; else NewImg2Addr = Part2Addr; // update ATSC clear partitin first if(ATSCAddr != ~0x0){ OldImg2Addr = NewImg2Addr; NewImg2Addr = ATSCAddr; } printf("\n\r[%s] New %x, Old %x", __FUNCTION__, NewImg2Addr, OldImg2Addr); if( NewImg2Addr==Part1Addr ){ if( file_info[2] > (Part2Addr-Part1Addr) ){ // firmware size too large printf("\n\r[%s] Part1 size < OTA size", __FUNCTION__); goto update_ota_exit; // or update to partition2 // NewImg2Addr = Part2Addr; } } #endif //Erase upgraded image 2 region if(NewImg2Len == 0){ NewImg2Len = file_info[2]; printf("\n\r[%s] NewImg2Len %d ", __FUNCTION__, NewImg2Len); if((int)NewImg2Len > 0){ NewImg2BlkSize = ((NewImg2Len - 1)/4096) + 1; printf("\n\r[%s] NewImg2BlkSize %d 0x%8x", __FUNCTION__, NewImg2BlkSize, NewImg2BlkSize); for( i = 0; i < NewImg2BlkSize; i++) flash_erase_sector(&flash, NewImg2Addr + i * 4096); }else{ printf("\n\r[%s] Size INVALID", __FUNCTION__); goto update_ota_exit; } } printf("\n\r[%s] NewImg2Addr 0x%x", __FUNCTION__, NewImg2Addr); // reset file_checksum.u = 0; // Write New Image 2 sector if(NewImg2Addr != ~0x0){ address = NewImg2Addr; printf("\n\r"); while(1){ memset(buf, 0, BUF_SIZE); read_bytes = read(server_socket, buf, BUF_SIZE); if(read_bytes == 0) break; // Read end if(read_bytes < 0){ printf("\n\r[%s] Read socket failed", __FUNCTION__); goto update_ota_exit; } checksum += file_checksum.c[0]; // not read end, this is not attached checksum checksum += file_checksum.c[1]; checksum += file_checksum.c[2]; checksum += file_checksum.c[3]; //printf("\n\r[%s] read_bytes %d", __FUNCTION__, read_bytes); #if 1 if(flash_stream_write(&flash, address + size, read_bytes, buf) < 0){ printf("\n\r[%s] Write sector failed", __FUNCTION__); goto update_ota_exit; } size += read_bytes; for(i = 0; i < read_bytes-4; i ++) checksum += buf[i]; file_checksum.c[0] = buf[read_bytes-4]; // checksum attached at file end file_checksum.c[1] = buf[read_bytes-3]; file_checksum.c[2] = buf[read_bytes-2]; file_checksum.c[3] = buf[read_bytes-1]; #else size += read_bytes; for(i = 0; i < read_bytes-4; i ++){ checksum += buf[i]; } file_checksum.c[0] = buf[read_bytes-4]; // checksum attached at file end file_checksum.c[1] = buf[read_bytes-3]; file_checksum.c[2] = buf[read_bytes-2]; file_checksum.c[3] = buf[read_bytes-1]; #endif } printf("\n\r"); printf("\n\rUpdate file size = %d checksum 0x%x attached checksum 0x%x", size, checksum, file_checksum.u); #if CONFIG_WRITE_MAC_TO_FLASH //Write MAC address if(!(mac[0]==0xff&&mac[1]==0xff&&mac[2]==0xff&&mac[3]==0xff&&mac[4]==0xff&&mac[5]==0xff)){ if(flash_write_word(&flash, FLASH_ADD_STORE_MAC, mac, ETH_ALEN) < 0){ printf("\n\r[%s] Write MAC failed", __FUNCTION__); goto update_ota_exit; } } #endif //printf("\n\r checksum 0x%x file_info 0x%x ", checksum, *(file_info)); #if CONFIG_CUSTOM_SIGNATURE for(i = 0; i < 8; i ++){ flash_read_word(&flash, NewImg2Addr + 0x28 + i *4, read_custom_sig + i); } printf("\n\r[%s] read_custom_sig %s", __FUNCTION__ , (char*)read_custom_sig); #endif // compare checksum with received checksum //if(!memcmp(&checksum,file_info,sizeof(checksum)) if( (file_checksum.u == checksum) #if CONFIG_CUSTOM_SIGNATURE && !strcmp((char*)read_custom_sig,custom_sig) #endif ){ //Set signature in New Image 2 addr + 8 and + 12 uint32_t sig_readback0,sig_readback1; flash_write_word(&flash,NewImg2Addr + 8, 0x35393138); flash_write_word(&flash,NewImg2Addr + 12, 0x31313738); flash_read_word(&flash, NewImg2Addr + 8, &sig_readback0); flash_read_word(&flash, NewImg2Addr + 12, &sig_readback1); printf("\n\r[%s] signature %x,%x, checksum 0x%x", __FUNCTION__ , sig_readback0, sig_readback1, checksum); #if SWAP_UPDATE if(OldImg2Addr != ~0x0){ flash_write_word(&flash,OldImg2Addr + 8, 0x35393130); flash_write_word(&flash,OldImg2Addr + 12, 0x31313738); flash_read_word(&flash, OldImg2Addr + 8, &sig_readback0); flash_read_word(&flash, OldImg2Addr + 12, &sig_readback1); printf("\n\r[%s] old signature %x,%x", __FUNCTION__ , sig_readback0, sig_readback1); } #endif printf("\n\r[%s] Update OTA success!", __FUNCTION__); ret = 0; } } update_ota_exit: if(buf) update_free(buf); if(server_socket >= 0) close(server_socket); if(param) update_free(param); TaskOTA = NULL; printf("\n\r[%s] Update task exit", __FUNCTION__); if(!ret){ printf("\n\r[%s] Ready to reboot", __FUNCTION__); ota_platform_reset(); } vTaskDelete(NULL); return; }