#include "base/define.h" #include "basechecker.h" #include "stdint.h" #include "EWUpdata.h" #include "driver/EWDriver.h" #include "base/delay.h" #include "hardware/adc_cfg.h" #include "base/utility.h" #include "hardware/power.h" #include "hardware/timer_cfg.h" #include "debug.h" #include "commend.h" #include "mystring.h" #include "mystdlib.h" #define UPDATA_PACK_LEN 128 #define UPDATA_BASE_ADDR 0x1000 #define UPDATA_DATA_LEN (11*1024) #define UPDATA_FLAG_ADDR (0x7c) #define BOOT_FLAG ((uint8_t []){0x99,0x66,0xaa,0x55}) #define UPDATA_FLAG ((uint8_t []){0xaa,0xbb,0xcc,0xdd}) #define UPDATA_CRC_ALL ((uint32_t *)(MC_CODE_ADDR+16*1024))[0] #define UPDATA_CRC_APP ((uint32_t *)(MC_CODE_ADDR+16*1024))[1] #define UPDATA_FILE_NAME ((const char *)(MC_CODE_ADDR+16*1024+8)) // 擦除 static uint8_t EW_bootErease(void) { uint8_t data[3]={0xfe,0x00,0x00}; uint8_t read[4]={0}; uint8_t ret=0; DMod_SendBytesXor(data,2,1); delay_os_ms(50); ret=DMod_ReadBytesXor(read,4,100); DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,",ret,read[0],read[1],read[2],read[3]); return ret; } static int cmd_jwt_boot_erase(list_def *argv) { int ret=0; ret=EW_bootErease(); return ret; } // 跳转 static uint8_t EW_bootJump(void) { uint8_t data[3]={0xf9,0x00,0x00}; uint8_t read[4]={0}; uint8_t ret=0; DMod_SendBytesXor(data,2,1); ret=DMod_ReadBytesXor(read,4,100); DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,",ret,read[0],read[1],read[2],read[3]); return ret; } static int cmd_jwt_boot_jump(list_def *argv) { int ret=0; ret=EW_bootJump(); return ret; } // 充电 static uint8_t EW_bootCharg(void) { uint8_t data[4]={0xf8,0x01,0x01,0x00}; uint8_t read[4]={0}; uint8_t ret=0; DMod_SendBytesXor(data,3,1); delay_ms(2); ret=DMod_ReadBytesXor(read,4,100); DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,",ret,read[0],read[1],read[2],read[3]); return ret; } static int cmd_jwt_boot_charg(list_def *argv) { int ret=0; ret=EW_bootCharg(); return ret; } // 放电 static uint8_t EW_bootDisCharg(void) { uint8_t data[4]={0xf8,0x01,0x00,0x00}; uint8_t read[4]={0}; uint8_t ret=0; DMod_SendBytesXor(data,3,1); ret=DMod_ReadBytesXor(read,4,100); DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,",ret,read[0],read[1],read[2],read[3]); return ret; } static int cmd_jwt_boot_discharg(list_def *argv) { int ret=0; ret=EW_bootDisCharg(); return ret; } // 发送数据 // len 最长为128字节 static uint8_t EW_bootWrite(uint16_t addr,uint8_t *d,uint16_t len) { uint8_t ret=0; uint8_t read[4]={0}; uint8_t *buf=rt_malloc(len+2+2+1); if(buf==RT_NULL) return 1; buf[0]=0xfc; buf[1]=2+len; buf[2]=addr&0xff; buf[3]=addr>>8; rt_memcpy(&buf[4],d,len); LED2_Out=0; DMod_SendBytesXor(buf,len+2+2,1); LED2_Out=1; ret=DMod_ReadBytesXor(read,4,100); rt_free(buf); if(ret){ DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,",ret,read[0],read[1],read[2],read[3]); } return ret; } // 校验 static uint8_t EW_bootCheckCrc(uint16_t adr_start,uint16_t adr_end,uint32_t *crc) { uint8_t ret=0; uint8_t cmd[7]={0xfb,0x04,adr_start&0xff,adr_start>>8,adr_end&0xff,adr_end>>8}; uint8_t read[4+4]={0}; DMod_SendBytesXor(cmd,6,1); delay_ms(10); ret=DMod_ReadBytesXor(read,8,100); if(ret==0){ if(crc){ *crc=(read[3]<<24)|(read[4]<<16)|(read[5]<<8)|(read[6]<<0); } } DBG_LOG("addr_start=0x%04x,addr_end=0x%04x.",adr_start,adr_end); DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,", ret,read[0],read[1],read[2],read[3],read[4],read[5],read[6],read[7]); return ret; } static int cmd_jwt_boot_checkcrc(list_def *argv) { int ret=0; uint32_t crc=0; ret=EW_bootCheckCrc(UPDATA_BASE_ADDR,UPDATA_BASE_ADDR+UPDATA_DATA_LEN,&crc); cmd_print("jwt crc32=0x%04x.",crc); //crc=Crc32Calu((uint32_t *)(MC_CODE_ADDR+UPDATA_BASE_ADDR),UPDATA_DATA_LEN); crc=UPDATA_CRC_APP; cmd_print("local crc32=0x%04x.",crc); return ret; } // 校验jwt程序的crc static int cmd_jwtcrc(list_def *argv) { int ret=0; uint32_t crc=0,crc2=0; crc=Crc32Calu((uint32_t *)(MC_CODE_ADDR+UPDATA_BASE_ADDR),UPDATA_DATA_LEN); crc2=UPDATA_CRC_APP; cmd_print("crc_calc=0x%08x,crc_rom=0x%08x.",crc,crc2); if(crc==crc2){ cmd_print("rom name:%s.",UPDATA_FILE_NAME); } return ret; } commend_export(jwtcrc,cmd_jwtcrc,"check jwt app crc32.") // 读取 static uint8_t EW_bootRead(uint16_t adr,uint8_t *buf,uint16_t len) { uint8_t ret=0; uint8_t cmd[7]={0xfa,0x03,adr&0xff,adr>>8,len}; uint16_t read_len=2+len+1+1; uint8_t *read=rt_malloc(read_len); if(read==RT_NULL) return 1; DMod_SendBytesXor(cmd,6,1); ret=DMod_ReadBytesXor(read,read_len,100); rt_memset(buf,0,len); if(ret==0) { rt_memcpy(buf,&read[3],len); } DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,",ret,read[0],read[1],read[2],read[3]); rt_free(read); return ret; } // app:读取数据 static int EW_appRead(void) { uint8_t read_buf[4]={0}; int ret=0; uint8_t addr=(uint8_t)(UPDATA_FLAG_ADDR/4); DBG_LOG("addr=0x%02x.",addr); ret=EW_ReadMTP(1,addr,read_buf,4); DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,",ret,read_buf[0],read_buf[1],read_buf[2],read_buf[3]); return ret; } static int cmd_jwt_app_read(list_def *argv) { int ret=0; ret=EW_appRead(); return ret; } // app:通信测试 static int EW_appCommTest(void) { // uint8_t data[4]={0x11,0x22}; // uint8_t ret; // DBG_LOG("send:%02x,%02x.",data[0],data[1]); // ret=EW_CommTest(data,2,300); // DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,",ret,data[0],data[1],data[2],data[3]); // return ret; return EW_appRead(); } static int cmd_jwt_app_commtest(list_def *argv) { int ret=0; ret=EW_appCommTest(); return ret; } // app:runbootloader static void EW_appRunBoot(void) { EW_Charge(1,0,0); delay_os_ms(6000); EW_RunBootLoader(1,1); DBG_LOG("run boot"); } static int cmd_jwt_app_runboot(list_def *argv) { int ret=0; EW_appRunBoot(); return ret; } #ifdef DEBUG commend_export(jwt_boot_erase,cmd_jwt_boot_erase,"jwt srase in boot") commend_export(jwt_boot_jump,cmd_jwt_boot_jump,"jwt jump in boot") commend_export(jwt_boot_charg,cmd_jwt_boot_charg,"jwt charg in boot") commend_export(jwt_boot_discharg,cmd_jwt_boot_discharg,"jwt discharg in boot") commend_export(jwt_boot_checkcrc,cmd_jwt_boot_checkcrc,"jwt checkcrc in boot") commend_export(jwt_app_read,cmd_jwt_app_read,"jwt read in app") commend_export(jwt_app_commtest,cmd_jwt_app_commtest,"jwt commtest in app") commend_export(jwt_app_runboot,cmd_jwt_app_runboot,"jwt turn to bootloader") #endif typedef struct{ // 充电时间 6000 int time_charg; // 加载app时间 6000 int time_loadapp; // 总线关断时间 1000 int time_poweroff; // 升级模式,0,无app时升级;1,无条件升级 int updata_mode; // 模块状态 int state; }ew_updata_def; // 硬复位 int EW_HardReset(ew_updata_def *e) { EW_BUS_OFF; delay_os_ms(e->time_poweroff); EW_BUS_ON; return 0; } // 判断模块在何种工作状态 1:boot 2:app // 3:boot失败且app也失败 int EW_CheckState(ew_updata_def *e) { uint16_t ret=0; delay_os_ms(100); ret=EW_bootCharg(); if(ret==0){ delay_os_ms(e->time_charg); e->state=1; }else{ EW_HardReset(e); delay_os_ms(e->time_loadapp); ret=EW_appCommTest(); delay_ms(5); if(ret==0){ e->state=2; }else{ e->state=3; } } return e->state; } // 跳转到app的方式 static int EW_TurnToBoot1(ew_updata_def *e) { DBG_LOG("turn to boot1"); delay_ms(5); EW_EnWriteMTP(0,1); delay_ms(5); EW_RunBootLoader(0,0); delay_os_ms(500); if(EW_bootCharg()==0) return 0; else return 1; } static int EW_TurnToBoot2(ew_updata_def *e) { DBG_LOG("turn to boot2"); delay_ms(5); EW_EnWriteMTP(0,1); delay_ms(5); EW_WriteMTP(0,(uint8_t)(UPDATA_FLAG_ADDR/4),BOOT_FLAG,4); delay_ms(5); return 1; } // 跳转到bootloader int EW_TurnToBoot(ew_updata_def *e) { typedef int (*turnfun)(ew_updata_def *e); turnfun func_table[]={EW_TurnToBoot1,EW_TurnToBoot2}; int ret=0; for(int i=0;i<2;i++){ if(e->state!=1){ ret=func_table[i](e); if(ret){ EW_HardReset(e); } EW_CheckState(e); }else{ break; } } return e->state; } void EW_PowerSet(int power) { if(power){ PowerCalibration_set(200,120); } else{ PowerCalibration_set(POWER_DEF_V,45); POWER_OFF; } } static void EW_ParamPrint(ew_updata_def *e) { DBG_LOG("time_charg=%d",e->time_charg); DBG_LOG("time_loadapp=%d",e->time_loadapp); DBG_LOG("time_poweroff=%d",e->time_poweroff); DBG_LOG("updata_mode=%d",e->updata_mode); } // 升级 void EW_Updata(void) { Checker_RunCfg_st *cfg=&checker_runcfg; uint16_t ret=0; uint8_t read_buf[4]={0}; uint8_t *data=(uint8_t *)MC_CODE_ADDR+UPDATA_BASE_ADDR; uint16_t len=UPDATA_DATA_LEN; uint16_t addr=UPDATA_BASE_ADDR; uint8_t pack_len=UPDATA_PACK_LEN; uint32_t crc=0; uint32_t crc_module=0; ew_updata_def ew_updata={0}; // 充电时间 6000 ew_updata.time_charg=checker_runcfg.params[0]; // 加载app时间 6000 ew_updata.time_loadapp=checker_runcfg.params[1]; // 总线关断时间 1000 ew_updata.time_poweroff=checker_runcfg.params[2]; // 升级模式,0,无app时升级;1,无条件升级 ew_updata.updata_mode=checker_runcfg.params[3]; // 校验jwt程序是否正常 crc=Crc32Calu((uint32_t *)(MC_CODE_ADDR+UPDATA_BASE_ADDR),UPDATA_DATA_LEN); if(crc!=UPDATA_CRC_APP) { ret=12; goto err; } EW_ParamPrint(&ew_updata); EW_PowerSet(1); ret=EW_CheckState(&ew_updata); if(ret==2){ // 在app中 if(ew_updata.updata_mode==0){ DBG_LOG("no need updata."); ret=0; goto err; } } ret=EW_TurnToBoot(&ew_updata); // ret!=1 跳转到bootloader失败 if(ret!=1) { DBG_WARN("turn to boot failed.ret=%d",ret); ret=1; goto err; } DBG_LOG("erase app"); ret=EW_bootErease(); if(ret) {ret=2;goto err;} delay_os_ms(600); while(len>0){ pack_len=len>UPDATA_PACK_LEN?UPDATA_PACK_LEN:len; LED1_Out=!LED1_Out; ret=EW_bootWrite(addr,data,pack_len); addr+=pack_len; data+=pack_len; len-=pack_len; if(ret) {ret=3;goto err;} delay_ms(1); } //crc=Crc32Calu((uint32_t *)(MC_CODE_ADDR+UPDATA_BASE_ADDR),UPDATA_DATA_LEN); crc=UPDATA_CRC_APP; DBG_LOG("local crc:0x%04x.",crc); ret=EW_bootCheckCrc(UPDATA_BASE_ADDR,UPDATA_BASE_ADDR+UPDATA_DATA_LEN,&crc_module); DBG_LOG("module crc:0x%04x.",crc_module); if(ret) {ret=4;goto err;} if(crc!=crc_module){ret=5;goto err;} delay_os_ms(50); ret=EW_bootJump(); if(ret) {ret=6;goto err;} delay_os_ms(ew_updata.time_loadapp); ret=EW_EnWriteMTP(0,1); if(ret) {ret=7;goto err;} DBG_LOG("EW_EnWriteMTP success."); delay_ms(5); ret=EW_WriteMTP(1,(uint8_t)(UPDATA_FLAG_ADDR/4),UPDATA_FLAG,4); if(ret) {ret=8;goto err;} DBG_LOG("EW_WriteMTP success."); delay_os_ms(20); ret=EW_ReadMTP(1,(uint8_t)(UPDATA_FLAG_ADDR/4),read_buf,4); if(ret) {ret=9;goto err;} if(memcmp(read_buf,UPDATA_FLAG,4)!=0){ DBG_LOG("read_buf=0x%02d,0x%02d,0x%02d,0x%02d.",read_buf[0],read_buf[1],read_buf[2],read_buf[3]); ret=10;goto err; } DBG_LOG("EW_ReadMTP check success."); delay_ms(5); EW_PowerSet(0); delay_os_ms(ew_updata.time_poweroff); EW_PowerSet(1); delay_os_ms(ew_updata.time_loadapp); ret=EW_appCommTest(); if(ret) {ret=11;goto err;} DBG_LOG("EW_appCommTest success."); err: DBG_LOG("ret=%d",ret); Checker_SetRtv(&ret,checker_runcfg.rtv_count); Checker_MaskResult(ret,checker_runcfg.task_info.runindex); } static int cmd_jwt_updata(list_def *argv) { int ret=0; checker_runcfg.params[0]=6000; checker_runcfg.params[1]=6000; checker_runcfg.params[2]=1000; checker_runcfg.params[3]=0; checker_runcfg.rtv_count=0; EW_Updata(); return ret; } commend_export(jwt_updata,cmd_jwt_updata,"jwt updata")