unsigned long getCrcPC(size_t start_byte, int size)// чтение из памяти crc { char* buf = NULL; buf = malloc(size); if (!buf) { //printf("no memory\n"); reset(7); return 1; } int err = flash_Read(start_byte, buf, size); //if (err != size) reset(); указать параметр unsigned long n = strtoul(buf, size, 10); free(buf); return n; }
// выделение памяти версии прошивки int getVer(size_t start_byte, int size)//если чтение из памяти версии { char* buf = NULL; buf = malloc(size); if (!buf) { //printf("no memory\n"); reset(7); return 1; } int err = flash_Read(start_byte, buf, size); //if (err != size) reset(); указать параметр int n = atol(buf); free(buf); return n; }
int nvm_init(void) { char *src, *dst, *bak; int sz_ram, magic, sz_nvm, pages; dst = __section_begin(".nvm.ram"); sz_ram = (int)__section_end(".nvm.ram") - (int)__section_begin(".nvm.ram"); if(sz_ram == 0) { //no nvm var is used nvm_flag_null = 0; return 0; } sz_ram = align(sz_ram, 4); pages = align(sz_ram + 8, FLASH_PAGE_SZ) / FLASH_PAGE_SZ; src = (char *)FLASH_ADDR(FLASH_PAGE_NR - pages); //rom 1 bak = (char *)FLASH_ADDR(FLASH_PAGE_NR - pages - pages); // rom 2 //rom 1 -> ram, always read & erase rom 1 in case of "rom1 not null!!!" flash_Read(&magic, src, 4); flash_Read(&sz_nvm, src + 4, 4); if(magic == NVM_MAGIC && sz_nvm == sz_ram) { flash_Read(dst, src + 8, sz_ram); //rom1 data is ok, rom1 -> rom 2 flash_Erase(bak, pages); flash_Write(bak + 4, &sz_nvm, 4); flash_Write(bak + 8, dst, sz_ram); flash_Write(bak + 0, &magic, 4); flash_Erase(src, pages); //erase rom 1 nvm_flag_null = 0; return 0; } //to avoid one more time erase op on an empty flash page if(sz_nvm != -1) { flash_Erase(src, pages); //erase rom 1 } //rom 2 -> ram src = bak; flash_Read(&magic, src, 4); flash_Read(&sz_nvm, src + 4, 4); if(magic == NVM_MAGIC && sz_nvm == sz_ram) { flash_Read(dst, src + 8, sz_ram); nvm_flag_null = 0; return 0; } //fail ... nvm_flag_null = 1; return -1; }
void LoadWifiConfig() { rtw_wifi_config_t local_config; uint32_t address; #ifdef STM32F10X_XL address = 0x08080000; //bank2 domain #else uint16_t sector_nb = FLASH_Sector_11; address = flash_SectorAddress(sector_nb); #endif printf("\r\nLoadWifiConfig(): Read from FLASH!\n"); flash_Read(address, (char *)&local_config, sizeof(local_config)); printf("\r\nLoadWifiConfig(): local_config.boot_mode=0x%x\n", local_config.boot_mode); printf("\r\nLoadWifiConfig(): local_config.ssid=%s\n", local_config.ssid); printf("\r\nLoadWifiConfig(): local_config.channel=%d\n", local_config.channel); printf("\r\nLoadWifiConfig(): local_config.security_type=%d\n", local_config.security_type); printf("\r\nLoadWifiConfig(): local_config.password=%s\n", local_config.password); if(local_config.boot_mode == 0x77665502) { wifi_setting.mode = RTW_MODE_AP; if(local_config.ssid_len > 32) local_config.ssid_len = 32; memcpy(wifi_setting.ssid, local_config.ssid, local_config.ssid_len); wifi_setting.ssid[local_config.ssid_len] = '\0'; wifi_setting.channel = local_config.channel; wifi_setting.security_type = local_config.security_type; if(local_config.password_len > 32) local_config.password_len = 32; memcpy(wifi_setting.password, local_config.password, local_config.password_len); wifi_setting.password[local_config.password_len] = '\0'; } else { LoadWifiSetting(); } }
/* unsigned long getCrcMK(size_t start_byte, int size) { uint32_t* buf = NULL; buf = malloc(size * 4); // size*4 количество байт в количеств слов 32бита if (!buf) { //printf("no memory\n"); reset(7); return 1; } int err = flash_Read(start_byte, buf, size * 4); // size*4 количество байт в количеств слов 32бита //if (err != size) reset(); указать параметр ошибки unsigned long resCrc = crc32(buf, size * 4); //оптимизировать free(buf); return resCrc; } */ int upd_module(size_t FW_AREA_START, size_t FW_AREA_END, size_t IMAGE_AREA_START, size_t FLASH_SZ, size_t FW_SIZE_NEW, size_t SECTOR_SZ) { //ХЕШ СУММУ сперва проверить если норм то { //------------------------------------------------ чтение версии---------------------------------------------- int verNewFw = getVer(FW_AREA_START, SECTOR_SZ, verSize, crcSize); //версия новой прошивки до 99999 //printf("ver new = %d\n", verNewFw); int verOldFw = getVer(FW_AREA_START, SECTOR_SZ, verSize, 0); //версия старой прошивки до 99999 //printf("ver old = %d\n", verOldFw); //--------------------------------------------crc пока не законченно------------------------------- /*unsigned long crc32PC = getCrcPC(FW_AREA_START + verSize, crcSize);//сразу после версии в памяти tempSizeNew = SECTOR_SZ; while (tempSizeNew < FW_SIZE_NEW) { unsigned long crc32MK = getCrcMK((FW_AREA_START + tempSizeNew), 16); //crc32PC } */ //---------------------------------дополнительные константы----------------------------------------------------------------- size_t NUMB_OF_SECT_NEW_FW = (FLASH_SZ - IMAGE_AREA_START) / SECTOR_SZ;// МАКС КОЛИЧЕСТВО СЕКТОРОВ НОВОГО ПРОЩИВКИ size_t NUMB_OF_SECT_OLD_FW = (FW_AREA_END - FW_AREA_START) / SECTOR_SZ;// МАКС КОЛИЧЕСТВО СЕКТОРОВ СТАРОЙ ПРОШИВКИ size_t IMAGE_AREA_FINISH = IMAGE_AREA_START; verNewFw = 2; //временно verOldFw = 1; if (verNewFw > verOldFw) { //---------------------------выделяем память под буфер размером SECTOR_SZ------------------------------ char* bufData = NULL; bufData = malloc(SECTOR_SZ); if (!bufData) { //printf("no memory\n"); reset(7); return 1; } //----------------------------------очищаем всю старую память занимаемую старой прошивкой------------------------------------ erase = flash_Erase(FW_AREA_START, NUMB_OF_SECT_OLD_FW); // sector Начальный сектор (нумерция с нуля) count Количество секторов, которые необходимо стереть. if (erase != 0)// если ноль ошибок нет { reset(1); return 1; } //-------------------до тех пор, пока реальный размер новой прошивки в памяти больше текущего считываемого сектора------------------------ tempSizeNew = 0; while (tempSizeNew < FW_SIZE_NEW) { //FW_SIZE_NEW реальный размер новой прошивки //IMAGE_AREA_START начальный адресс новой прошивки //IMAGE_AREA_FINISH начальный адресс новой прошивки увеличивается на сектор //TEMP_SECTOR_SZ временный размер сектора меняется в последнем проходе //---------------------------------читаем из памяти в буфер-------------------------------------------------------------------- while (read != SECTOR_SZ) { read = flash_Read(IMAGE_AREA_START + tempSizeNew, bufData, SECTOR_SZ); // чтение C начала новой прошивки по одному сектору с указателя bufData return Количество реально считанных байт if (read != SECTOR_SZ) { countRead++; if (countRead == 2)//повторная попытка выполнить неудачна { reset(2); return 1; } } } countRead = 0; read = -1; //printf("Read addr = %d ", IMAGE_AREA_START + tempSizeNew); //---------------------------------пишем из буфера в память------------------------------------------------------------- while (write != SECTOR_SZ) { write = flash_Write(FW_AREA_START + tempSizeNew, bufData, SECTOR_SZ);// запись с начала новой прошивки по одному сектору с указателя DATA return Количество реально записанных байт if (write != SECTOR_SZ) { erase = flash_Erase(IMAGE_AREA_FINISH, SECTOR_SZ); countWrite++; if (countWrite == 2)// повторная попытка выполнить неудачна { reset(3); return 1; } } } countWrite = 0; write = -1; //printf("Write addr = %d ", FW_AREA_START + tempSizeNew); //--------------------------переход к следующему сектору-------------------------------------------------- tempSizeNew += SECTOR_SZ; countupd++; //printf(" countupd = %d \n", countupd); } //printf("size FW_AREA_START + tempSizeNew + buffer = %d \n", tempSizeNew); free(bufData); return 0; } } }
static void update_ota_local_task(void *param) { int server_socket = 0; struct sockaddr_in server_addr; char *buf; int read_bytes, size = 0, i; update_cfg_local_t *cfg = (update_cfg_local_t*)param; uint32_t address, checksum = 0; #if CONFIG_WRITE_MAC_TO_FLASH char mac[ETH_ALEN]; #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; } // Erase config sectors if(flash_EraseSector(CONFIG_SECTOR) < 0){ printf("\n\r[%s] Erase sector failed", __FUNCTION__); goto update_ota_exit; } #if CONFIG_WRITE_MAC_TO_FLASH // Read MAC address if(flash_Read(FLASH_ADD_STORE_MAC, mac, ETH_ALEN) < 0){ printf("\n\r[%s] Read MAC error", __FUNCTION__); goto update_ota_exit; } #endif // Erase update sectors for(i = UPDATE_SECTOR; i <= FLASH_Sector_11; i += 8){ if(flash_EraseSector(i) < 0){ printf("\n\r[%s] Erase sector failed", __FUNCTION__); goto update_ota_exit; } } // Write update sectors address = flash_SectorAddress(UPDATE_SECTOR); printf("\n\r"); while(1){ 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; } if(flash_Wrtie(address + size, buf, read_bytes) < 0){ printf("\n\r[%s] Write sector failed", __FUNCTION__); goto update_ota_exit; } size += read_bytes; for(i = 0; i < read_bytes; i ++) checksum += buf[i]; printf("\rUpdate file size = %d ", size); } #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_Wrtie(FLASH_ADD_STORE_MAC, mac, ETH_ALEN) < 0){ printf("\n\r[%s] Write MAC failed", __FUNCTION__); goto update_ota_exit; } } #endif // Write config sectors address = flash_SectorAddress(CONFIG_SECTOR); if( (flash_Wrtie(address, (char*)&size, 4) < 0) || (flash_Wrtie(address+4, (char*)&checksum, 4) < 0) ){ printf("\n\r[%s] Write sector failed", __FUNCTION__); goto update_ota_exit; } printf("\n\r[%s] Update OTA success!", __FUNCTION__); 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__); vTaskDelete(NULL); return; }
static void update_ota_cloud_task(void *param) { struct updater_ctx ctx; char *buf, flag_a = 0; int read_bytes, size = 0, i; uint32_t address, checksum = 0; update_cfg_cloud_t *cfg = (update_cfg_cloud_t*)param; uint16_t a = 0; #if CONFIG_WRITE_MAC_TO_FLASH char mac[ETH_ALEN]; #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_1; } // Init ctx if(updater_init_ctx(&ctx, (char*)cfg->repository, (char*)cfg->file_path) != 0) { printf("\n\r[%s] Cloud ctx init failed", __FUNCTION__); goto update_ota_exit_1; } printf("\n\r[%s] Firmware link: %s, size = %d bytes, checksum = 0x%08x, version = %s\n", __FUNCTION__, ctx.link, ctx.size, ctx.checksum, ctx.version); // Erase config sectors for(i = CONFIG_SECTOR; i < APPLICATION_SECTOR; i += FLASH_PAGE_SIZE){ if(flash_EraseSector(i) < 0){ printf("\n\r[%s] Erase sector failed", __FUNCTION__); goto update_ota_exit; } } #if CONFIG_WRITE_MAC_TO_FLASH // Read MAC address if(flash_Read(FLASH_ADD_STORE_MAC, mac, ETH_ALEN) < 0){ printf("\n\r[%s] Read MAC error", __FUNCTION__); goto update_ota_exit; } #endif // Erase update sectors for(i = UPDATE_SECTOR; i < FLASH_Sector_0 + FLASH_SIZE; i += FLASH_PAGE_SIZE){ if(flash_EraseSector(i) < 0){ printf("\n\r[%s] Erase sector failed", __FUNCTION__); goto update_ota_exit; } } // Write update sectors address = UPDATE_SECTOR; printf("\n\r"); while(ctx.bytes < ctx.size){ read_bytes = updater_read_bytes(&ctx, (unsigned char*)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; } if(flag_a == 0){ if(read_bytes % 2 != 0){ a = buf[read_bytes - 1]; flag_a = 1; if(flash_Wrtie(address + size, buf, read_bytes - 1) < 0){ printf("\n\r[%s] Write sector failed", __FUNCTION__); goto update_ota_exit; } size += read_bytes - 1; } else{ if(flash_Wrtie(address + size, buf, read_bytes) < 0){ printf("\n\r[%s] Write sector failed", __FUNCTION__); goto update_ota_exit; } size += read_bytes; } } else{ a = buf[0]<< 8 |a; if(flash_Wrtie(address + size, (char*)(&a), 2) < 0){ printf("\n\r[%s] Write sector failed", __FUNCTION__); goto update_ota_exit; } size += 2; a = 0; flag_a = 0; if((read_bytes - 1) % 2 != 0){ a = buf[read_bytes - 1]; flag_a = 1; if(flash_Wrtie(address + size, buf + 1, read_bytes - 2) < 0){ printf("\n\r[%s] Write sector failed", __FUNCTION__); goto update_ota_exit; } size += read_bytes - 2; } else{ if(flash_Wrtie(address + size, buf + 1, read_bytes - 1) < 0){ printf("\n\r[%s] Write sector failed", __FUNCTION__); goto update_ota_exit; } size += read_bytes - 1; } } for(i = 0; i < read_bytes; i ++) checksum += buf[i]; printf("\rUpdate file size = %d/%d bytes ", ctx.bytes, ctx.size); } if(flag_a){ if(flash_Wrtie(address + size, (char*)(&a), 2) < 0){ printf("\n\r[%s] Write sector failed", __FUNCTION__); goto update_ota_exit; } size += 1; } printf("\n\r[%s] ctx checksum = %08x, computed checksum = %08x\n", __FUNCTION__, ctx.checksum, checksum); if(checksum != ctx.checksum){ printf("\n\r[%s] Checksum error", __FUNCTION__); goto update_ota_exit; } #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_Wrtie(FLASH_ADD_STORE_MAC, mac, ETH_ALEN) < 0){ printf("\n\r[%s] Write MAC failed", __FUNCTION__); goto update_ota_exit; } } #endif // Write config sectors address = CONFIG_SECTOR; if( (flash_Wrtie(address, (char*)&size, 4) < 0) || (flash_Wrtie(address+4, (char*)&checksum, 4) < 0) ){ printf("\n\r[%s] Write sector failed", __FUNCTION__); goto update_ota_exit; } printf("\n\r[%s] Update OTA success!", __FUNCTION__); update_ota_exit: updater_free_ctx(&ctx); update_ota_exit_1: if(buf) update_free(buf); if(param) update_free(param); TaskOTA = NULL; printf("\n\r[%s] Update task exit", __FUNCTION__); vTaskDelete(NULL); return; }