#include #include #include #include "FreeRTOS.h" #include "chip.h" #include "board.h" #include "serial.h" #include "sysinfo.h" #include "conversation_protocol.h" #include "sfud.h" #include "ota_update.h" #include "updatefile.h" #include "romfile.h" #include "animation.h" #include "ff_stdio.h" #include "awtk.h" #include "ota_protocol.h" int flash_copy_demo(void); extern uint8_t bt_upgrade_flag; #if DEVICE_TYPE_SELECT != EMMC_FLASH #include "ff_sfdisk.h" #endif typedef enum { UART_FRAME_START, UART_FRAME_FILEINFO, UART_FRAME_FILEXFER, UART_FRAME_FINISH, } eUartFrameType; typedef enum { UUP_STATE_IDLE, UUP_STATE_START, UUP_STATE_GET_FILEINFO, UUP_STATE_FILE_TFR, UUP_STATE_END, } eUartUpdateState; #define UUP_ACK_OK 1 #define UUP_ACK_FAIL 0 #define UUP_MAX_FILE_SIZE 0x1000000 #define UUP_RX_FRAME_NUM 16 #define UUP_MAX_LOADER_SIZE STEPLDR_MAX_SIZE//0x10000 static int uup_status = UUP_STATE_IDLE; static int uup_file_type = 0; static int uup_file_size = 0; static int uup_packet_num = 0; static int uup_rev_packet = 0; static int uup_rev_len = 0; static char uup_filename[32]; static FF_FILE *uup_file = NULL; #define UUP_PACKET_SIZE 128 #define UUP_MAX_FRAME_LEN (UUP_PACKET_SIZE + 16) #define UUP_PACKET_A27_SIZE 4096 #define UUP_MAX_FRAME_A27_LEN (UUP_PACKET_A27_SIZE + 16) #define UUP_RX_FRAME_NUM 16 #define BYTESPERPAGE 256 #define PAGESPERSECTORS 16 #define UUP_BUF_SIZE (BYTESPERPAGE * PAGESPERSECTORS) #define IMAGE_RW_SIZE 0x10000 #define NEW_APPLDR_CHECKSUM_OFFSET 0x14 #define AMT630_BIN_OFFSET 0x41000 #define BOOTANIM_BIN_OFFSET 0x741000 #define ROM_BIN_OFFSET 0xb41000 #define NEW_APPFOOSET 0x17F0000 #define AMT630_BIN_MAX_SIZE 0x700000 /* #define AMT630_BIN_OFFSET 0x41000 #define BOOTANIM_BIN_OFFSET 0x501000//0x341000 #define ROM_BIN_OFFSET 0x801000 #define NEW_APPFOOSET 0xb01000 #define AMT630_BIN_MAX_SIZE 0x4c0000 */ static uint32_t uup_app_offset; static uint32_t uup_burn_offset; static unsigned char uup_buf[4096]; static unsigned int uup_buf_len = 0; static unsigned int checksum = 0,calc_checksum = 0xffffffff; static void uup_send_ack(UartPort_t *uap, int type, int ret) { /*unsigned char buf[7] = {0x55, 0x80, 0xc5, 0x02, 0x00, 0x00, 0x00}; int i; buf[4] = type; buf[5] = ret; for (i = 1; i < 6; i++) buf[6] ^= buf[i]; iUartWrite(uap, buf, 7, pdMS_TO_TICKS(100));*/ unsigned char buf[8] = {0x55, 0x80, 0xc5, 0x02, 0x00, 0x00, 0x00, 0x00}; int i; buf[5] = type; buf[6] = ret; if(ret == 0){ Set_sys_power_on_self_test(100); Set_sys_return_demo(2); Set_sys_plan(0); Set_sys_pace(0); bt_upgrade_flag = 0; } for (i = 1; i < 7; i++) buf[7] ^= buf[i]; // printf("630->uart:"); // for(uint8_t j=0;j<8;j++){ // printf("%02x ",buf[j]); // } // printf("\n"); iUartWrite(uap, buf, 8, pdMS_TO_TICKS(100)); } void uup_ota_update(UartPort_t *uap, uint8_t *framebuf, size_t len) { int frametype = framebuf[0]; uint8_t *buf = framebuf + 1; unsigned int framelen; unsigned int packetnum; sfud_flash *sflash = sfud_get_device(0); SysInfo *sysinfo = GetSysInfo(); //printf("uup_ota_update frametype =%d \n",frametype); switch (frametype) { case UART_FRAME_START: printf("UART3_Modification_Type .\n"); UART3_Modification_Type(); vTaskDelay(10); printf("start sfud erase flash .\n"); //擦除flash uup_app_offset = NEW_APPFOOSET; uup_burn_offset = uup_app_offset; //uup_send_ack(uap, frametype, UUP_ACK_OK); //Set_sys_power_on_self_test(150); printf("erase add %X , size %X .\r\n",uup_app_offset,AMT630_BIN_MAX_SIZE); if(sfud_erase(sflash, uup_app_offset, AMT630_BIN_MAX_SIZE)==SFUD_SUCCESS){ vTaskDelay(100); printf("UART3_Type_regression .\n"); UART3_Type_regression(); vTaskDelay(100); printf("UART_FRAME_START sfud erase ok.\n"); uup_send_ack(uap, frametype, UUP_ACK_OK); }else{ vTaskDelay(100); printf("UART3_Type_regression .\n"); UART3_Type_regression(); vTaskDelay(100); printf("UART_FRAME_START sfud erase fail.\n"); uup_send_ack(uap, frametype, UUP_ACK_FAIL); } uup_status = UUP_STATE_START; break; case UART_FRAME_FILEINFO: if (uup_status != UUP_STATE_START && uup_status != UUP_STATE_GET_FILEINFO) { uup_send_ack(uap, frametype, UUP_ACK_FAIL); break; } uup_file_type = buf[0]; if (uup_file_type > UPFILE_TYPE_LNCHEMMC) { printf("Rev wrong file type %d.\n", uup_file_type); uup_send_ack(uap, frametype, UUP_ACK_FAIL); break; } uup_packet_num = (buf[1] << 16) | (buf[2] << 8) | buf[3]; uup_file_size = 128 * uup_packet_num; if (uup_file_size > AMT630_BIN_MAX_SIZE) { printf("Rev wrong file size.\n"); printf("uup_file_size = 0x%x ,uup_packet_num = 0x%x .\n",uup_file_size,uup_packet_num); uup_send_ack(uap, frametype, UUP_ACK_FAIL); break; } printf("uup_file_size = 0x%x .\n",uup_file_size); uup_packet_num = uup_packet_num/32; Set_sys_plan(uup_packet_num); printf("uup_packet_num = %d .\r\n",uup_packet_num); uup_rev_packet = 0; uup_send_ack(uap, frametype, UUP_ACK_OK); uup_status = UUP_STATE_GET_FILEINFO; calc_checksum = 0xffffffff; break; case UART_FRAME_FILEXFER: if (uup_status != UUP_STATE_GET_FILEINFO && uup_status != UUP_STATE_FILE_TFR) { uup_send_ack(uap, frametype, UUP_ACK_FAIL); break; } packetnum = buf[0]; if ((uup_rev_packet & 0xff) != packetnum) { printf("Wrong packet number.\n"); //printf("buf 0 - 4 : 0x%x ,0x%x ,0x%x ,0x%x ,0x%x \n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]); //printf("packetnum = 0x%x,uup_rev_packet = 0x%x \n",packetnum,uup_rev_packet); uup_send_ack(uap, frametype, UUP_ACK_FAIL); break; } //printf("uup_rev_packet==0 ---------TURE\n"); //printf("uup_rev_packet %d.\n", uup_rev_packet); if (uup_rev_packet==0) { //第一条数据保存其crc校验码 /*if (uup_file_type == UPFILE_TYPE_WHOLE) { UpFileHeader *header = (UpFileHeader*)&buf[1]; if (header->magic != MKTAG('U', 'P', 'D', 'F')) { printf("Wrong whole file magic.\n"); uup_send_ack(uap, frametype, UUP_ACK_FAIL); break; } checksum = header->checksum; sysinfo->app_size = header->files[0].size; printf("sysinfo->appsize = 0x%x", sysinfo->app_size); }else if (uup_file_type == UPFILE_TYPE_RESOURCE) { RomHeader *header = (RomHeader *)&buf[1]; if (header->magic != MKTAG('R', 'O', 'M', 'A')) { printf("Wrong resource file magic.\n"); uup_send_ack(uap, frametype, UUP_ACK_FAIL); break; } checksum = header->checksum; } else if (uup_file_type == UPFILE_TYPE_ANIMATION) { BANIHEADER *header = (BANIHEADER *)&buf[1]; if (header->magic != MKTAG('B', 'A', 'N', 'I')) { printf("Wrong animation file magic.\n"); uup_send_ack(uap, frametype, UUP_ACK_FAIL); break; } checksum = header->checksum; } else */ if (uup_file_type == UPFILE_TYPE_APP) {//代码文件 unsigned int magic = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24); if (magic != UPFILE_APP_MAGIC) { printf("Wrong app file magic.\n"); uup_send_ack(uap, frametype, UUP_ACK_FAIL); break; } unsigned char *tmp = buf + 1 + NEW_APPLDR_CHECKSUM_OFFSET; checksum = tmp[0] | (tmp[1] <<8) | (tmp[2] << 16) | (tmp[3] << 24); }else if (uup_file_type == UPFILE_TYPE_ANIMATION) {//动画文件 BANIHEADER *header = (BANIHEADER *)&buf[1]; if (header->magic != MKTAG('B', 'A', 'N', 'I')) { printf("Wrong animation file magic.\n"); uup_send_ack(uap, frametype, UUP_ACK_FAIL); break; } checksum = header->checksum; }else if (uup_file_type == UPFILE_TYPE_RESOURCE) {//资源文件 RomHeader *header = (RomHeader *)&buf[1]; if (header->magic != MKTAG('R', 'O', 'M', 'A')) { printf("Wrong resource file magic.\n"); uup_send_ack(uap, frametype, UUP_ACK_FAIL); break; } checksum = header->checksum; } printf(" file_type = %d ,No1.checksum = 0x%x\n",uup_file_type,checksum); } framelen = len - 2; //printf("framelen = %d ,uup_packet_num =%d ,uup_rev_packet = %d \n",framelen,uup_packet_num,uup_rev_packet); /* only last frame size is less than UUP_PACKET_SIZE */ if (framelen > UUP_PACKET_A27_SIZE || (framelen < UUP_PACKET_A27_SIZE && uup_rev_packet < (uup_packet_num-1))) { //UUP_PACKET_A27_SIZE printf("Wrong packet len.\n"); printf("uup_rev_packet = %d, uup_packet_num = %d \n",uup_rev_packet,(uup_packet_num-1)); uup_send_ack(uap, frametype, UUP_ACK_FAIL); break; } memcpy(uup_buf + uup_buf_len, buf+1, framelen); uup_buf_len += framelen; uup_rev_packet++; //uup_send_ack(uap, frametype, UUP_ACK_OK); if (uup_buf_len == UUP_BUF_SIZE) { printf("uup_rev_packet = %d , save_data.\n",uup_rev_packet); uup_send_ack(uap, frametype, UUP_ACK_OK); Set_sys_pace(uup_rev_packet); //printf("addr=0x%x,size=%x\n",uup_burn_offset,framelen); //sfud_erase_write(sflash, uup_burn_offset, UUP_BUF_SIZE, uup_buf); sfud_write(sflash, uup_burn_offset, UUP_BUF_SIZE, uup_buf); if (uup_rev_packet == 1){//UUP_BUF_SIZE/UUP_PACKET_SIZE) { //printf("enter1 uup_rev_packet = %d \n",uup_rev_packet); /*if (uup_file_type == UPFILE_TYPE_WHOLE) { UpFileHeader *pheader = (UpFileHeader *)uup_buf; pheader->checksum = 0; } else if (uup_file_type == UPFILE_TYPE_RESOURCE) { RomHeader *pheader = (RomHeader *)uup_buf; pheader->checksum = 0; } else if (uup_file_type == UPFILE_TYPE_ANIMATION) { BANIHEADER *pheader = (BANIHEADER *)uup_buf; pheader->checksum = 0; } else if (uup_file_type == UPFILE_TYPE_APP) {*/ if (uup_file_type == UPFILE_TYPE_APP) {//代码文件 unsigned int *tmp = (unsigned int *)(uup_buf + NEW_APPLDR_CHECKSUM_OFFSET); *tmp = 0; }else if (uup_file_type == UPFILE_TYPE_ANIMATION) {//动画文件 BANIHEADER *pheader = (BANIHEADER *)uup_buf; pheader->checksum = 0; }else if (uup_file_type == UPFILE_TYPE_RESOURCE) {//资源文件 RomHeader *pheader = (RomHeader *)uup_buf; pheader->checksum = 0; } //} } calc_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, calc_checksum);//计算校验和 uup_buf_len =0; uup_burn_offset += UUP_BUF_SIZE; }else if (uup_buf_len > UUP_BUF_SIZE) { printf("loader file is too large.\n"); uup_send_ack(uap, frametype, UUP_ACK_FAIL); break; } /*memcpy(&uup_sysinfo, &buf[2], sizeof(SysInfo)); sfud_erase_write(sflash, uup_burn_offset, framelen, &buf[1]);//128字节写一次 uup_burn_offset += framelen;*/ uup_status = UUP_STATE_FILE_TFR; break; case UART_FRAME_FINISH: if (uup_status != UUP_STATE_FILE_TFR && uup_status != UART_FRAME_FINISH) { uup_send_ack(uap, frametype, UUP_ACK_FAIL); break; } if (!buf[0]) { printf("update end with error!\n"); uup_send_ack(uap, frametype, UUP_ACK_FAIL); uup_status = UUP_STATE_END; break; } framelen = len - 2; //printf("finish calc_checksum =%x\n",calc_checksum); if(uup_buf_len){//若最后一包数据不为0 则存数据并且继续计算校验和 //sfud_erase_write(sflash, uup_burn_offset, uup_buf_len, uup_buf); sfud_write(sflash, uup_burn_offset, uup_buf_len, uup_buf); //若数据为32 即首次的4k 那么将其置为0 if (uup_rev_packet <= 1){//< UUP_BUF_SIZE / UUP_PACKET_SIZE) { printf("enter2 uup_rev_packet = %d \n",uup_rev_packet); /*if (uup_file_type == UPFILE_TYPE_WHOLE) { UpFileHeader *pheader = (UpFileHeader *)uup_buf; pheader->checksum = 0; } else if (uup_file_type == UPFILE_TYPE_RESOURCE) { RomHeader *pheader = (RomHeader *)uup_buf; pheader->checksum = 0; } else if (uup_file_type == UPFILE_TYPE_ANIMATION) { BANIHEADER *pheader = (BANIHEADER *)uup_buf; pheader->checksum = 0; } else if (uup_file_type == UPFILE_TYPE_APP) {*/ if (uup_file_type == UPFILE_TYPE_APP) { unsigned int *checksum = (unsigned int *)(uup_buf + NEW_APPLDR_CHECKSUM_OFFSET); *checksum = 0; }else if (uup_file_type == UPFILE_TYPE_ANIMATION) { BANIHEADER *pheader = (BANIHEADER *)uup_buf; pheader->checksum = 0; }else if (uup_file_type == UPFILE_TYPE_RESOURCE) { RomHeader *pheader = (RomHeader *)uup_buf; pheader->checksum = 0; } } printf("enter2 uup_buf_len =%d calc_checksum================0x%x\n",uup_buf_len,calc_checksum); calc_checksum = xcrc32(uup_buf, uup_buf_len, calc_checksum); Set_sys_pace(0); Set_sys_upgrade(1); } /*if (calc_checksum != checksum) { printf("checksum error ! ! ! .\r\n"); }else{ printf("checksum ok .\r\n"); }*/ if (calc_checksum != checksum) { printf("calc_checksum = 0x%02x,checksum = 0x%02x.\n",calc_checksum,checksum); printf("whole crc check after burn fail!\n"); uup_send_ack(uap, frametype, UUP_ACK_FAIL); uup_rev_packet = 0; checksum = 0; calc_checksum = 0xffffffff; uup_buf_len = 0; framelen = 0; break; } else { uup_send_ack(uap, frametype, UUP_ACK_OK); vTaskDelay(1000); UART3_Modification_Type(); printf("uap close .\r\n"); printf("test amt630h update ok!\n"); sysinfo->image_offset=0x40000; sysinfo->reserved[9] = uup_file_type; sysinfo->upgrade_flag=uup_buf_len; sysinfo->upgrade_appsize=uup_file_size; SaveSysInfo(); vTaskDelay(500); printf("TaskDelay 500ms SaveSysInfo .\n"); flash_copy_demo(); wdt_cpu_reboot(); } uup_rev_packet = 0; checksum = 0; calc_checksum = 0xffffffff; uup_buf_len = 0; framelen = 0; uup_status = UUP_STATE_END; break; } } int flash_copy_demo(void) { uint32_t calchecksum,appchecksum,imageoff,new_appoffset,new_appsize; int i; uint8_t *buf; sfud_flash *sflash = sfud_get_device(0); printf("enter copy flash .\n"); new_appsize=uup_file_size; //根据串口升级的协议获取 new_appoffset = NEW_APPFOOSET; //升级的程序可以固定写在这个地址,预留3M if(uup_file_type == UPFILE_TYPE_APP){ imageoff = AMT630_BIN_OFFSET; //固定的 运行区固定地址 }else if(uup_file_type == UPFILE_TYPE_ANIMATION){ imageoff = BOOTANIM_BIN_OFFSET; //固定的 运行区固定地址 }else if(uup_file_type == UPFILE_TYPE_RESOURCE){ imageoff = ROM_BIN_OFFSET; } //imageoff = AMT630_BIN_OFFSET; //固定的 运行区固定地址 printf("copy flash init ok.\n"); Set_sys_plan((new_appsize/IMAGE_RW_SIZE)+1); printf("new_appsize = %x ,start flash copy .\n",new_appsize); // sfud_qspi_fast_read_enable(sfud_get_device(0), 1); // printf("sfud_qspi_fast_read_enable ok.\n"); buf = pvPortMalloc(IMAGE_RW_SIZE); if (!buf) { printf("%s %d malloc %d bytes fail.\n", __FUNCTION__, __LINE__, IMAGE_RW_SIZE); return -1; } printf("start copy flash ok.\n"); for(i=0;ichecksum; pheader->checksum = 0; }else if (uup_file_type == UPFILE_TYPE_RESOURCE) {//资源文件 RomHeader *pheader = (RomHeader *)buf; appchecksum = pheader->checksum; pheader->checksum = 0; } printf("file_type = %d. %X\r\n",uup_file_type,appchecksum); calchecksum = xcrc32(buf, IMAGE_RW_SIZE, 0xffffffff); printf("i=0 calchecksum = 0x%X.\n",calchecksum); } else { calchecksum = xcrc32(buf, IMAGE_RW_SIZE, calchecksum); printf("i=%d ,r_add = 0x%X ,w_add = 0x%X , calchecksum = 0x%X.\n",i,new_appoffset+IMAGE_RW_SIZE*i,imageoff+IMAGE_RW_SIZE*i,calchecksum); } } if(new_appsize%IMAGE_RW_SIZE) { uint32_t red_add,wri_add,size,count; int k; count = (new_appsize%IMAGE_RW_SIZE )/0x1000; red_add = new_appoffset+new_appsize- new_appsize%IMAGE_RW_SIZE; wri_add = imageoff+new_appsize- new_appsize%IMAGE_RW_SIZE; size = 0x1000; printf("count = %d .\n",count); for(k=0;kapp_size = new_appsize; sysinfo->image_offset=0x40000; sysinfo->upgrade_flag = 0; sysinfo->upgrade_appsize =0; sysinfo->reserved[9] = 0; SaveSysInfo(); vTaskDelay(500); wdt_cpu_reboot(); return 0; } else { SysInfo *sysinfo = GetSysInfo(); if(uup_file_type == UPFILE_TYPE_APP) sysinfo->app_size = new_appsize; sysinfo->image_offset=0x40000; sysinfo->upgrade_flag = 0; sysinfo->upgrade_appsize =0; sysinfo->reserved[9] = 0; SaveSysInfo(); vTaskDelay(500); printf("crc32 ERROR\r\n"); bt_upgrade_flag = 0; return -1; } }