#include "Updata.h" #include "LT768_Lib.h" #include "string.h" #include "CRC.h" #include "eflash_drv.h" #include "Uart_Vcom.h" #include "wdt_drv.h" //extern u8 W25Q256; extern u8 Flash_type; //extern u32 Flash_size; u32 Flash_ID = 0; void num_to_char(char *buf,u8 num) { if(num >= 100) { buf[0] = '1'; buf[1] = '0'; buf[2] = '0'; } else if(num >=10) { buf[0] = ' '; buf[1] = (num / 10) + '0'; buf[2] = (num % 10) + '0'; } else { buf[0] = ' '; buf[1] = ' '; buf[2] = num + '0'; } buf[3] = '%'; buf[4] = '\0'; } u8 buff[4*1024]; signed char Flash_Updata(const char *buf,char type) //正确返回1,错误返回0 { u64 addr = 0; u8 num = 0; u32 block_num = 0; u32 blockremain = 0; u32 file_size = 0; u32 BIN_CRC = 0; u32 Check_BIN_CRC = 0; u32 Check_num = 0; char run_flag = 0; char showbuff[10]; FATFS fs; FIL fsrc; FRESULT res; UINT br; f_mount(&fs,"0:",1); res = f_open(&fsrc, buf, FA_READ); if(res != FR_OK) { res = f_open(&fsrc, buf, FA_READ); } if(res == FR_OK) { file_size = f_size(&fsrc); if (Flash_ID == 0xef13) { if (file_size > 1024*1024*1) { LT768_Print_Internal_Font_String(370,LINE1,NG_color,White,"NG"); LT768_Print_Internal_Font_String(10,LINE4,Red,White,"File size exceeds Flash capacity"); while(1) WDT_FeedDog(); } } else if (Flash_ID == 0xef14) { if (file_size > 1024*1024*2) { LT768_Print_Internal_Font_String(370,LINE1,NG_color,White,"NG"); LT768_Print_Internal_Font_String(10,LINE4,Red,White,"File size exceeds Flash capacity"); while(1) WDT_FeedDog(); } } else if (Flash_ID == 0xef15) { if (file_size > 1024*1024*4) { LT768_Print_Internal_Font_String(370,LINE1,NG_color,White,"NG"); LT768_Print_Internal_Font_String(10,LINE4,Red,White,"File size exceeds Flash capacity"); while(1) WDT_FeedDog(); } } else if (Flash_ID == 0xef16) { if (file_size > 1024*1024*8) { LT768_Print_Internal_Font_String(370,LINE1,NG_color,White,"NG"); LT768_Print_Internal_Font_String(10,LINE4,Red,White,"File size exceeds Flash capacity"); while(1) WDT_FeedDog(); } } else if (Flash_ID == 0xef17 || Flash_ID == 0x5e17) { if (file_size > 1024*1024*16) { LT768_Print_Internal_Font_String(370,LINE1,NG_color,White,"NG"); LT768_Print_Internal_Font_String(10,LINE4,Red,White,"File size exceeds Flash capacity"); while(1) WDT_FeedDog(); } } else if (Flash_ID == 0xef18) { if (file_size > 1024*1024*32) { LT768_Print_Internal_Font_String(370,LINE1,NG_color,White,"NG"); LT768_Print_Internal_Font_String(10,LINE4,Red,White,"File size exceeds Flash capacity"); while(1) WDT_FeedDog(); } } else if (Flash_ID == 0xefaa21) { MUC_SS_flag = 0; if (W25N01GV_ReadID() == 0xefaa21) { if (file_size > (1024*1024*128 - 20*1024) *2) { LT768_Print_Internal_Font_String(370,LINE1,NG_color,White,"NG"); LT768_Print_Internal_Font_String(10,LINE4,Red,White,"File size exceeds Flash capacity"); while(1) WDT_FeedDog(); } } else if (file_size > (1024*1024*128 - 20*1024)) { LT768_Print_Internal_Font_String(370,LINE1,NG_color,White,"NG"); LT768_Print_Internal_Font_String(10,LINE4,Red,White,"File size exceeds Flash capacity"); while(1) WDT_FeedDog(); } MUC_SS_flag = 1; } // printf("size=%d\r\n",file_size); for(;;) //从SD卡读数据写入SPI_FLASH { WDT_FeedDog(); //闪动===================================================================== { if(run_flag == run_time) { LT768_Print_Internal_Font_String(20,LINE5,Black,White,"* "); } else if(run_flag == run_time*2) { LT768_Print_Internal_Font_String(20,LINE5,Black,White," *"); run_flag = 0; } run_flag++; } //======================================================================== //进度===================================================================== if(MUC_SS_flag == 0 && type != 0) num = (addr + 2048*64*(1024-20)) * 100.0 / file_size; else num = addr * 100.0 / file_size; //if(num == 100) num = 99; num_to_char(showbuff,num); if(type == 1||type == 2) //UartTFT-II_Flash.bin 片选1 { LT768_Print_Internal_Font_String(310,LINE1,Progress_color,White,showbuff); } else if(type == 0) //UartTFT-II_Flash.bin 片选0 { #if UartTFT_Flash_0 LT768_Print_Internal_Font_String(275,LINE4,Progress_color,White,showbuff); #endif } //======================================================================== //读文件烧录 u8 time = 0; u32 File_CRC = 0; u32 Flash_CRC = 0; char BBM_flag = 0; res=f_read(&fsrc,buff,2*1024,&br); if(res||(br == 0)) { f_close(&fsrc); break; } if(type!=2) //type为2,不校验CRC { if(addr == 0 && ((type == 1 && MUC_SS_flag == 1) || type == 0)) { BIN_CRC = buff[379]<<24|buff[378]<<16|buff[377]<<8|buff[376]; memset(&buff[372], 0xFF, 12); } File_CRC = GetCrc32(buff,br,0); } for(;;) { WDT_FeedDog(); if(Flash_type == 0 )//NorFlash { block_num = addr/(64*1024); blockremain = addr% (64*1024); if(blockremain == 0) //新BLOCK执行擦除 W25QXX_BlockErase64KB(block_num); W25QXX_Write_NoCheck(buff,addr,br);//写入数据 // W25QXX_Read(&buff[2*1024],addr,br);//立刻拿回数据 } else //NandFlash { block_num = addr/(128*1024); blockremain = addr% (128*1024); if(blockremain == 0) //新BLOCK执行擦除 W25N01GV_Erase_Block(block_num); W25N01GV_Write_NoCheck(buff,addr,br);//写入数据 } if(type!=2) //type为2,不校验CRC { if(Flash_type == 0 ) W25QXX_Read(&buff[2*1024],addr,br);//立刻拿回数据 else W25N01GV_Read_NoCheck(&buff[2*1024],addr,br);//立刻拿回数据 Flash_CRC = GetCrc32(&buff[2*1024],br,0); if(File_CRC != Flash_CRC)//对比数据是否正确 { time++; } else { break; } if(time == 3) //三次了,退出报错,NG CRC { if(Flash_type == 0 )//NorFlash { return -1; } else //NandFlash { if(W25N01GV_BBM(block_num) == 0) //BBM OK { BBM_flag = 1; break; } else //BBM Fail { return -2; } } } } else { break; } } addr += br; //Flash地址增加 if(BBM_flag) { f_lseek(&fsrc,block_num*128*1024); addr = block_num*128*1024; } if(addr == 2048*64*(1024-20)) { MUC_SS_flag = 0; //更换片选 addr = 0; } //======================================================================== } if(type == 1 || type == 2) { MUC_SS_flag = 1; } //校验整体CRC======================================================================== if(type!=2) //type为2,不校验CRC { LT768_Print_Internal_Font_String(10,LINE4,File_name_color,White,"Checking CRC"); for(;;) { WDT_FeedDog(); //进度===================================================================== num = Check_num * 100.0 / file_size; num_to_char(showbuff,num); LT768_Print_Internal_Font_String(310,LINE4,Progress_color,White,showbuff); //闪动===================================================================== { if(run_flag == run_time) { LT768_Print_Internal_Font_String(20,LINE5,Black,White,"* "); } else if(run_flag == run_time*2) { LT768_Print_Internal_Font_String(20,LINE5,Black,White," *"); run_flag = 0; } run_flag++; } //======================================================================== unsigned short Read_size; if(file_size - Check_num>= 2048) Read_size = 2048; else Read_size = file_size - Check_num; if(Flash_type == 0 )//NorFlash { W25QXX_Read(buff,Check_num,Read_size); } else //NandFlash { if(MUC_SS_flag == 0 && type == 1) { W25N01GV_Read_NoCheck(buff,Check_num - 2048*64*(1024-20),Read_size); } else W25N01GV_Read_NoCheck(buff,Check_num,Read_size); } Check_BIN_CRC = GetCrc32(buff,Read_size,Check_BIN_CRC); Check_num += Read_size; if(Check_num == 2048*64*(1024-20)) { MUC_SS_flag = 0; //更换片选 } if(Check_num == file_size) { Check_num = 0; break; } } if(Check_BIN_CRC != BIN_CRC) //NG CRC { LT768_Print_Internal_Font_String(370,LINE4,NG_color,White,"NG"); //LT768_Print_Internal_Font_String(46 ,LINE5,Black,White,"NG: CRC error"); LT768_Print_Internal_Font_String(10 ,LINE5,Black,White,"Result:"); LT768_Print_Internal_Font_String(96,LINE5,Red,White,"Failed"); while(1) WDT_FeedDog(); return -3; } LT768_DrawSquare_Fill(0,LINE4,LCD_XSIZE_TFT-1,LINE5-1,Back_color); } //======================================================================== return 0; //能跑到这里的,只能是好的 } else //打开文件失败,返回文件系统结果代号 { return res; } } //判断块是不是坏块,参数为块编号; 好块返回0,坏块返回1; uint8_t Check_BadBlock(uint16_t block_num) { uint16_t i= 0 ,j= 0; uint32_t addr = block_num*128*1024; W25N01GV_Erase_Block(block_num); addr = block_num*128*1024; for(i=0;i<64;i++) { memset(buff,i,sizeof(buff)); W25N01GV_Write_NoCheck(buff,addr,2048); addr+=2048; } addr = block_num*128*1024; for(i=0;i<64;i++) { W25N01GV_Read_NoCheck(buff,addr,2048); for(j=0;j<2048;j++) { if(buff[j] != i) return 1; } addr+=2048; } W25N01GV_Erase_Block(block_num); addr = block_num*128*1024; for(i=0;i<64;i++) { memset(buff,0xA5,sizeof(buff)); W25N01GV_Write_NoCheck(buff,addr,2048); addr+=2048; } addr = block_num*128*1024; for(i=0;i<64;i++) { W25N01GV_Read_NoCheck(buff,addr,2048); for(j=0;j<2048;j++) { if(buff[j] != 0xA5) return 1; } addr+=2048; } W25N01GV_Erase_Block(block_num); addr = block_num*128*1024; for(i=0;i<64;i++) { memset(buff,0xFF,sizeof(buff)); W25N01GV_Write_NoCheck(buff,addr,2048); addr+=2048; } addr = block_num*128*1024; for(i=0;i<64;i++) { W25N01GV_Read_NoCheck(buff,addr,2048); for(j=0;j<2048;j++) { if(buff[j] != 0xFF) return 1; } addr+=2048; } return 0; } u8 uart_nand_BBM_flag = 0; signed char W25N01GV_BBM(unsigned short Block_num) //OK 0,Fail 1 { BBM LUT[20]; if(Check_BadBlock(Block_num) == 0) //检查是否真的是坏块 return 1; if((W25N01GV_ReadSR(0xC0) & 0x40) == 0x40) // 替换列表已经满了 { return 1; } W25N01GV_Read_BBM_LUT(LUT); //读回Flash里的坏块管理表数据 // for(int i=0;i<20;i++) // printf("LBA[%d]:%x PBA[%d]:%x \r\n",i,LUT[i].LBA,i,LUT[i].PBA); // printf("\r\n"); // while(1); unsigned short Block_replace_num = 1023; unsigned char Find_good_block_result = 0; char run_flag = 0; char time = 0; for(;;) { WDT_FeedDog(); Find_good_block_result = 0; //闪动===================================================================== if(!uart_nand_BBM_flag) { if(run_flag == run_time) { LT768_Print_Internal_Font_String(20,LINE5,Black,White,"* "); } else if(run_flag == run_time*2) { LT768_Print_Internal_Font_String(20,LINE5,Black,White," *"); run_flag = 0; } run_flag++; } //======================================================================== for(int i=0;i<20;i++) { if(LUT[i].PBA == Block_replace_num) //替换列表里有该替换地址 { if((LUT[i].LBA & 0xC000) == 0x8000) //该替换序列使能并有效 { Find_good_block_result = 0; break; } else { Find_good_block_result = 1; break; } } else //没有该替换地址 { Find_good_block_result = 1; } } if(Find_good_block_result == 1) //该Block没有在替换类表里,再判断该Block是否为好的块 { if(Check_BadBlock(Block_replace_num) == 0) //好块 { break; } else //坏块 { time++; Block_replace_num--; Find_good_block_result = 0; } } else { time++; if(time == 21) { Find_good_block_result = 0; break; } Block_replace_num--; } } uart_nand_BBM_flag = 0; if(Find_good_block_result == 0) //无法找到好块 { return 1; } else //找到好块 { char Replace_flag = 1; // printf("Block_replace_num:%x\r\n",Block_replace_num); // while(1); if(Block_num>=Block_replace_num) return 1; W25N01GV_Bad_Block_Replace(Block_num,Block_replace_num); W25N01GV_Read_BBM_LUT(LUT); for(int i=0;i<20;i++) { // printf("LBA[%d]:%x PBA[%d]:%x \r\n",i,LUT[i].LBA,i,LUT[i].PBA); if(((LUT[i].LBA & 0x3FFF) == Block_num) && (LUT[i].PBA == Block_replace_num)) { if((LUT[i].LBA & 0xC000) == 0x8000) //Enable link { Replace_flag = 0; } else { Replace_flag = 1; } } } if(Replace_flag) return 1; else if(Replace_flag == 0) return 0; } } signed char APP_Updata(const char *buf) //OK 0; NG crc -1, BBM -2;None 回对应的标号。 { u8 num = 0; u32 addr = 0; u32 file_size = 0; char showbuff[10]; u32 BIN_CRC = 0; u32 Check_BIN_CRC = 0; char run_flag = 0; u32 Check_num = 0; u32 val_flag=0; FATFS fs; FIL fsrc; FRESULT res; UINT br; printf("enter app updata\r\n"); EFLASH_Init(g_sys_clk/1000); EFLASH_SetWritePermission(); printf("next f_mount\r\n"); //f_mount(&fs,"0:",1); printf(" next f_open!!\r\n"); res = f_open(&fsrc, buf, FA_READ); if(res == FR_OK) { printf("open mcu1 OK!!\r\n"); // printf("res=%d\r\n",res); file_size = f_size(&fsrc); // printf("size=%d\r\n",file_size); //读取文件获取文件总体CRC============================================== for(;;) { WDT_FeedDog(); //闪动===================================================================== // { // if(run_flag == run_time) // { // LT768_Print_Internal_Font_String(10,LINE5,Black,White,"* "); // } // else if(run_flag == run_time*2) // { // LT768_Print_Internal_Font_String(10,LINE5,Black,White," *"); // run_flag = 0; // } // run_flag++; // } //======================================================================== res = f_read(&fsrc,buff,4*1024,&br); if(res||(br == 0)) { f_lseek(&fsrc,0); //不关闭文件,将文件读取指针指向文件开头 break; } BIN_CRC = GetCrc32(buff,br,BIN_CRC); } // printf("CRC:%x\r\n",BIN_CRC); //===================================================================== for(;;) { WDT_FeedDog(); //闪动===================================================================== { if(run_flag == run_time) { LT768_Print_Internal_Font_String(20,LINE5,Black,White,"* "); } else if(run_flag == run_time*2) { LT768_Print_Internal_Font_String(20,LINE5,Black,White," *"); run_flag = 0; } run_flag++; } //======================================================================== //进度==================================================================== num = addr * 100 / file_size; if(num == 100) num = 99; num_to_char(showbuff,num); LT768_Print_Internal_Font_String(310,LINE2,Progress_color,White,showbuff); //======================================================================== //读文件烧录 u8 time = 0; u32 File_CRC = 0; u32 Flash_CRC = 0; res=f_read(&fsrc,buff,2*1024,&br); if(res||(br == 0)) { f_close(&fsrc); break; } File_CRC = GetCrc32(buff,br,0); for(;;) { WDT_FeedDog(); EFLASH_Write(APP_ADDR+addr,buff,br);//写入数据 for(u16 i = 0;i= 4000) Read_size = 4000; else Read_size = file_size - Check_num; for(u16 i = 0;i