#include "tran_for_slave.h" #include "debug.h" #include "mymisc.h" #include "mystdlib.h" #include "board.h" #include "dev_flash.h" #include "prot_uc.h" #include "coder_lib.h" #include "JQ_PSDGenerate.h" #include "mystring.h" #include "coder_judge.h" #include "JQ_UIDGenerate.h" #include "transmit.h" #include "elec_det.h" #include "crc.h" #include "dev_backup.h" typedef struct{ ucport_def u; rt_timer_t timer; // int *host_type;// 主机接口类型0串口,1can }slave_def; static slave_def *slave_creat(void) { slave_def *u=calloc(1,sizeof(slave_def)); //u->host_type=app_variable("host_if",0,0); return u; } static void slave_del(ucport_def *u) { slave_def *s=(slave_def *)u; CHECK_DO(s->timer,rt_timer_delete); free(u); } // 获取检测结果 static int check_result_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str) { slave_def *s=(slave_def *)u; array_def *r=elec_check_result(); if(r){ emit tran_reply_signal(u->p,arr_temp(r)); } return 0; } static ucport_def *check_result(tran_def *t, uint8_t cmd,array_def *data) { int ret=0; slave_def *u=slave_creat(); u->u.p=t; u->u.del=slave_del; u->u.dolater=check_result_dolater; u->u.dolater(&u->u,cmd,data,"ok"); return (ucport_def *)u; } transmit_export(ym_slave,0x02,check_result) transmit_export(ym_slave,0x18,check_result) // 设置硬件版本号 static int write_hw_version_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str) { int value=arr_get(data,0)|(arr_get(data,1)<<8); emit tran_reply_signal(u->p,arr_temp(elec_write_hardversion(value))); return 0; } static ucport_def *write_hw_version(tran_def *t, uint8_t cmd,array_def *data) { int ret=0; slave_def *u=slave_creat(); u->u.p=t; u->u.del=slave_del; u->u.dolater=write_hw_version_dolater; u->u.dolater(&u->u,cmd,data,"ok"); return (ucport_def *)u; } transmit_export(ym_slave,0x03,write_hw_version) // 设置电阻校准值 static int write_resistor_cbv_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str) { int value=arr_get(data,0)|(arr_get(data,1)<<8); emit tran_reply_signal(u->p,arr_temp(elec_write_resistor_cbv(value))); return 0; } static ucport_def *write_resistor_cbv(tran_def *t, uint8_t cmd,array_def *data) { int ret=0; int value=arr_get(data,0)|(arr_get(data,1)<<8); slave_def *u=slave_creat(); u->u.p=t; u->u.del=slave_del; u->u.dolater=write_resistor_cbv_dolater; u->u.dolater(&u->u,cmd,data,"ok"); return (ucport_def *)u; } transmit_export(ym_slave,0x04,write_resistor_cbv) // 测量桥丝阻值 static int check_resistor_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str) { uint8_t index=0; if(data){ index=arr_get(data,0); } emit tran_reply_signal(u->p,arr_temp(elec_check_resistor(index))); return 0; } static ucport_def *check_resistor(tran_def *t, uint8_t cmd,array_def *data) { int ret=0; slave_def *u=slave_creat(); u->u.p=t; u->u.del=slave_del; u->u.dolater=check_resistor_dolater; u->u.dolater(&u->u,cmd,data,"ok"); return (ucport_def *)u; } transmit_export(ym_slave,0x05,check_resistor) // 根据方案检测 typedef struct{ int submit_running; int submit_delay;// 自动上报间隔 int submit_times;// 自动上报次数 tran_def *tran; uint8_t cmd; int host_type; array_def *data; array_def *(*check_fun)(array_def *uid); }check_def; static check_def g_check; static void check_set_data(check_def *u,array_def *data) { CHECK_DO(u->data,arr_delete); u->data=arr_duplicate(data); } static void check_submit_later(void *t) { check_def *s=(check_def *)t; s->submit_times--; if(s->submit_running&&(s->submit_times>0)){ array_def *ret=elec_check_result(); if(ret!=0){ emit tran_send_signal(s->tran,s->cmd,ret); // s->submit_delay=150; s->submit_delay+=elec_local_addr()*3; }else{ //while(1); } later_execute(check_submit_later,s,s->submit_delay); }else{ s->submit_running=0; s->submit_times=0; s->cmd=0; } } static void check_later(void *t) { check_def *s=(check_def *)t; if(s->check_fun){ s->check_fun(s->data); } if(s->host_type==1) { s->submit_times=10; s->submit_running=1; s->submit_delay=elec_local_addr()*10+200; later_execute(check_submit_later,s,s->submit_delay); }else{ s->cmd=0; } } static int check_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str) { slave_def *s=(slave_def *)u; check_def *c=&g_check; array_def *r=arr_creat(); if(c->cmd==0){ c->cmd=cmd; c->tran=s->u.p; check_set_data(c,data); later_execute(check_later,c,10); elec_check_result_clear(); } if(c->cmd==cmd){ arr_append(r,0); }else{ arr_append(r,2); } if(c->cmd==cmd){ emit tran_reply_signal(u->p,arr_temp(r)); }else{ arr_delete(r); } return 0; } static ucport_def *check_self(tran_def *t, uint8_t cmd,array_def *data, array_def *(*fun)(array_def *)) { int ret=0; check_def *c=&g_check; slave_def *u=slave_creat(); u->u.p=t; u->u.del=slave_del; u->u.dolater=check_dolater; c->check_fun=fun; u->u.dolater(&u->u,cmd,data,"ok"); return (ucport_def *)u; } static ucport_def *check_with_scheme(tran_def *t, uint8_t cmd,array_def *data) { check_def *c=&g_check; c->host_type=*(int *)app_variable("host_if",0,0); return check_self(t,cmd,data,elec_check_with_scheme); } transmit_export(ym_slave,0x0b,check_with_scheme) transmit_export(ym_slave,0x0c,check_with_scheme) static ucport_def *check_code(tran_def *t, uint8_t cmd,array_def *data) { check_def *c=&g_check; c->host_type=0; return check_self(t,cmd,data,elec_code); } transmit_export(ym_slave,0x17,check_code) // 停止上报 static int stop_submit_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str) { g_check.submit_running=0; g_check.cmd=0; array_def *r=arr_creat(); arr_append(r,0); emit tran_reply_signal(u->p,arr_temp(r)); return 0; } static ucport_def *stop_submit(tran_def *t, uint8_t cmd,array_def *data) { int ret=0; slave_def *u=slave_creat(); u->u.p=t; u->u.del=slave_del; u->u.dolater=stop_submit_dolater; u->u.dolater(&u->u,cmd,data,"ok"); return (ucport_def *)u; } transmit_export(ym_slave,0x14,stop_submit) // 定义地址宏 // 本程序中程序下载地址不是这个地址,在此用来计算偏移量 #define MCU_APP_ADDR_BASE 0x8004000 #define MCU_TASKID_ADDR_BASE 0x803f000 #define MCU_JWT_ADDR_BASE 0x803B000 // 定义升级结构体 typedef struct{ uint8_t device_state; uint32_t flash_addr; uint32_t flash_addr_base; int erased; }updata_def; static updata_def g_updata; // 查询设备状态,第一次返回在app,如果设置了跳转指令则返回在bootloader // 1:app;2:bootleader static int device_state_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str) { array_def *r=arr_creat(); arr_append(r,g_updata.device_state+1); emit tran_reply_signal(u->p,arr_temp(r)); return 0; } static ucport_def *device_state(tran_def *t, uint8_t cmd,array_def *data) { int ret=0; slave_def *u=slave_creat(); u->u.p=t; u->u.del=slave_del; u->u.dolater=device_state_dolater; u->u.dolater(&u->u,cmd,data,"ok"); return (ucport_def *)u; } transmit_export(ym_slave,0xf9,device_state) // 跳转至bootloader,这里只是改变标志,实际还是在app中 static int turn_to_bootloader_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str) { g_updata.device_state=1; array_def *r=arr_creat(); arr_append(r,0); emit tran_reply_signal(u->p,arr_temp(r)); return 0; } static ucport_def *turn_to_bootloader(tran_def *t, uint8_t cmd,array_def *data) { int ret=0; slave_def *u=slave_creat(); u->u.p=t; u->u.del=slave_del; u->u.dolater=turn_to_bootloader_dolater; u->u.dolater(&u->u,cmd,data,"ok"); return (ucport_def *)u; } transmit_export(ym_slave,0xf8,turn_to_bootloader) // 生成文件头 static uint32_t creat_file_head(uint32_t addr,const char *name) { uint8_t *td=calloc(FLASH_FILE_HEAD_SIZE,sizeof(uint8_t)); // 文件大小和文件名 memcpy(td,name,strlen(name)); // used字段 ((flash_file *)td)->used=0xffffffff; flash_write((uint8_t *)addr,td,FLASH_FILE_HEAD_SIZE); free(td); return addr+FLASH_FILE_HEAD_SIZE; } // 擦除app空间 static int erase_app_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str) { flash_erase_app2(); g_updata.flash_addr=creat_file_head((uint32_t)flash_get_app2(),"slave_app.pkt"); array_def *r=arr_creat(); arr_append(r,0); emit tran_reply_signal(u->p,arr_temp(r)); return 0; } static ucport_def *erase_app(tran_def *t, uint8_t cmd,array_def *data) { int ret=0; slave_def *u=slave_creat(); u->u.p=t; u->u.del=slave_del; u->u.dolater=erase_app_dolater; u->u.dolater(&u->u,cmd,data,"ok"); return (ucport_def *)u; } transmit_export(ym_slave,0xfe,erase_app) // 写入数据 // 因为添加了文件头,实际写入地址应该偏移一个文件头的长度 static int write_data_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str) { uint32_t addr=(arr_get(data,0))|(arr_get(data,1)<<8)|(arr_get(data,2)<<16)|(arr_get(data,3)<<24); int len=arr_length(data)-4; int ret=0; uint32_t offset=addr-MCU_APP_ADDR_BASE; addr=g_updata.flash_addr+offset; ret=flash_write((uint8_t *)addr,&arr_data(data)[4],len); array_def *r=arr_creat(); arr_append(r,ret); emit tran_reply_signal(u->p,arr_temp(r)); return 0; } static ucport_def *write_data(tran_def *t, uint8_t cmd,array_def *data) { int ret=0; slave_def *u=slave_creat(); u->u.p=t; u->u.del=slave_del; u->u.dolater=write_data_dolater; u->u.dolater(&u->u,cmd,data,"ok"); return (ucport_def *)u; } transmit_export(ym_slave,0xfc,write_data) // 校验并跳转 static int ceck_crc_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str) { uint32_t addr_start=(arr_get(data,0))|(arr_get(data,1)<<8)|(arr_get(data,2)<<16)|(arr_get(data,3)<<24); uint32_t addr_end=(arr_get(data,4))|(arr_get(data,5)<<8)|(arr_get(data,6)<<16)|(arr_get(data,7)<<24); uint32_t crc32=(arr_get(data,8))|(arr_get(data,9)<<8)|(arr_get(data,10)<<16)|(arr_get(data,11)<<24); uint32_t crc32_local=0; int len=addr_end-addr_start; addr_start=g_updata.flash_addr; crc32_local=crc_crc32((uint8_t *)addr_start,len); int ret=(crc32!=crc32_local); if(ret){ DBG_WARN("crc32 not equal,crc=0x%04x,crc_local=0x%04x",crc32,crc32_local); } array_def *r=arr_creat(); arr_append(r,ret); emit tran_reply_signal(u->p,arr_temp(r)); if(ret==0){ later_execute((void (*)(void *))bk_reboot_updata,0,100); } return 0; } static ucport_def *ceck_crc(tran_def *t, uint8_t cmd,array_def *data) { int ret=0; slave_def *u=slave_creat(); u->u.p=t; u->u.del=slave_del; u->u.dolater=ceck_crc_dolater; u->u.dolater(&u->u,cmd,data,"ok"); return (ucport_def *)u; } transmit_export(ym_slave,0xfb,ceck_crc) // 写入数据,这个命令会自动擦除 // 因为添加了文件头,实际写入地址应该偏移一个文件头的长度 static int write_data2_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str) { uint32_t addr=(arr_get(data,0))|(arr_get(data,1)<<8)|(arr_get(data,2)<<16)|(arr_get(data,3)<<24); int len=arr_length(data)-4; int ret=0; if(strcmp(err_str,"ok")!=0){ return -1; } if((addr)==MCU_TASKID_ADDR_BASE){ if(g_updata.erased==0){ flash_erase_scheme(); g_updata.flash_addr=creat_file_head((uint32_t)flash_get_scheme(),"scheme.bin"); g_updata.flash_addr_base=MCU_TASKID_ADDR_BASE; elec_scheme_deinit(); g_updata.erased=1; } }else if((addr)==MCU_JWT_ADDR_BASE){ if(g_updata.erased==0){ flash_erase_jwtcode(); g_updata.flash_addr=creat_file_head((uint32_t)flash_get_jwtcode(),"jwtcode.jwt"); g_updata.flash_addr_base=MCU_JWT_ADDR_BASE; g_updata.erased=1; } } uint32_t offset=addr-g_updata.flash_addr_base; addr=g_updata.flash_addr+offset; ret=flash_write((uint8_t *)addr,&arr_data(data)[4],len); array_def *r=arr_creat(); arr_append(r,ret); emit tran_reply_signal(u->p,arr_temp(r)); if(ret){ g_updata.erased=0; } return 0; } static ucport_def *write_data2(tran_def *t, uint8_t cmd,array_def *data) { int ret=0; slave_def *u=slave_creat(); u->u.p=t; u->u.del=slave_del; u->u.dolater=write_data2_dolater; u->u.dolater(&u->u,cmd,data,"ok"); return (ucport_def *)u; } transmit_export(ym_slave,0x11,write_data2) // 重新加载方案 static int load_scheme_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str) { int ret=0; array_def *r=arr_creat(); arr_append(r,ret); emit tran_reply_signal(u->p,arr_temp(r)); // 此处如果重启的话会丢失缓存 // later_execute((void (*)(void *))bk_reboot_app,0,100); g_updata.erased=0; ret=elec_scheme_init(); return 0; } static ucport_def *load_scheme(tran_def *t, uint8_t cmd,array_def *data) { int ret=0; slave_def *u=slave_creat(); u->u.p=t; u->u.del=slave_del; u->u.dolater=load_scheme_dolater; u->u.dolater(&u->u,cmd,data,"ok"); return (ucport_def *)u; } transmit_export(ym_slave,0x15,load_scheme) // 获取自检参数 static int bootinfo_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str) { emit tran_reply_signal(u->p,arr_temp(elec_bootinfo())); return 0; } static ucport_def *bootinfo(tran_def *t, uint8_t cmd,array_def *data) { int ret=0; slave_def *u=slave_creat(); u->u.p=t; u->u.del=slave_del; u->u.dolater=bootinfo_dolater; u->u.dolater(&u->u,cmd,data,"ok"); return (ucport_def *)u; } transmit_export(ym_slave,0x13,bootinfo) // 写缓存 static int write_fatbuf_dolater(ucport_def *u,uint8_t cmd,array_def *data,char *err_str) { emit tran_reply_signal(u->p,arr_temp(elec_write_fat_buff(data))); return 0; } static ucport_def *write_fatbuf(tran_def *t, uint8_t cmd,array_def *data) { int ret=0; slave_def *u=slave_creat(); u->u.p=t; u->u.del=slave_del; u->u.dolater=write_fatbuf_dolater; u->u.dolater(&u->u,cmd,data,"ok"); return (ucport_def *)u; } transmit_export(ym_slave,0x19,write_fatbuf)