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; }
int nvm_save(void) { char *src, *dest, *bak; int magic = NVM_MAGIC; int sz_ram, pages; src = __section_begin(".nvm.ram"); sz_ram = (int)__section_end(".nvm.ram") - (int)__section_begin(".nvm.ram"); if(sz_ram == 0) return 0; sz_ram = align(sz_ram, 4); pages = align(sz_ram + 8, FLASH_PAGE_SZ) / FLASH_PAGE_SZ; dest = (char *)FLASH_ADDR(FLASH_PAGE_NR - pages); //rom 1 bak = (char *)FLASH_ADDR(FLASH_PAGE_NR - pages - pages); // rom 2 //ram -> rom 1 flash_Write(dest + 4, &sz_ram, 4); flash_Write(dest + 8, src, sz_ram); flash_Write(dest + 0, &magic, 4); //ram -> rom 2 flash_Erase(bak, pages); flash_Write(bak + 4, &sz_ram, 4); flash_Write(bak + 8, src, sz_ram); flash_Write(bak + 0, &magic, 4); //erase rom 1 flash_Erase(dest, pages); return 0; }
/* 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; } } }