#include "tran_for_checker.h" #include "debug.h" #include "mymisc.h" #include "mystdlib.h" #include "board.h" #include "dev_flash.h" #include "tcp.h" #include "prot_uc.h" #include "handle_for_checker.h" #include "compiler_info.h" #include "dev_backup.h" typedef struct{ ucport_def u; void (*doexert)(ucport_def *u); uint8_t ack_num; int ret_skip; int ack_size; uint8_t ack[0]; }check_def; // 判断检测数据是否超限,返回填充的字节个数 static int in_range(const uint8_t *src_data,uint8_t *range) { const scheme_def *s=check_scheme(); int temp; for(int i=0;irange_num;i++) { temp=src_data[i*2]|(src_data[i*2+1]<<8); if(temp>=s->range[i].min&&temp<=s->range[i].max){ range[i/8]&=~(1<<(i%8)); }else{ range[i/8]|=(1<<(i%8)); } } DBG_LOG("range_num=%d, ",s->range_num); return (s->range_num+7)/8; } // 检测完成 static void check_end(ucport_def *u,port_mcu *src,void *data,int ack,char *err_str) { check_def *w=(check_def *)u; uint8_t addr=port_get_addr(src); if(addr<=0||addr>20){ DBG_WARN("addr err:%d",addr); return; } int return_size=w->ret_skip; uint8_t *ack_d=&w->ack[(addr-1)*return_size]; if(ack==0) { // 复制流程结果 memcpy(ack_d,arr_data(data),8);ack_d+=8; // 返回参数校验,跳过8字节的流程执行位 ack_d+=in_range(arr_data(data)+8+8,ack_d); // 复制返回参数,跳过8字节的流程执行位 memcpy(ack_d,arr_data(data)+8+8,check_scheme()->range_num*2); } else { // 复制为0xff 无效数据 memset(ack_d,0xff,return_size); } w->ack_num++; if(w->ack_num>=20) { array_def *a=arr_creat(); arr_append(a,0); arr_appends(a,w->ack,w->ack_size); emit tran_send_signal(w->u.p,0x31,arr_temp(a)); tran_set_busy(w->u.p,0); } } static void check_del(ucport_def *u) { free(u); } static ucport_def *check(tran_def *t, uint8_t cmd,array_def *data) { int return_size=(check_scheme()->range_num*2+8+(check_scheme()->range_num+7)/8); check_def *u=calloc(1,sizeof(check_def)+return_size*20); u->ret_skip=return_size; u->ack_size=return_size*20; u->u.p=t; u->u.del=check_del; u->u.doend=check_end; DBG_LOG("check: skip=%d",u->ret_skip); tran_set_busy(t,1); for(int i=0;i<20;i++) { port_mcu *mcu=tran_get_portm(u->u.p,i); // 这里打开检测 if(mcu){ port_start(mcu,check_creat(check_scheme())); } } array_def *a=arr_creat(); arr_append(a,0); emit tran_reply_signal(u->u.p,arr_temp(a)); return (ucport_def *)u; } transmit_export(ym_checker,0x30,check) /* 自检 和 参数设置 命令是批检仪和赋码仪都有的命令 应赋码仪上位机的要求,赋码仪多了一个 "通道" 的数据位 目前使用判断的方式,设备为赋码仪方式工作时命令的发送的返回都解析这个 "通道" */ __packed typedef struct{ char build_time[20]; char softverion[8]; int runtime; uint8_t wdog; char devicetype[12]; uint8_t localip[4]; uint8_t hostip[4]; uint16_t hostport; uint8_t localid; uint32_t schemeid; uint32_t slave_online; }local_bootinfo; typedef struct{ ucport_def u; void (*doexert)(ucport_def *u); uint8_t ack_num; uint8_t slave_num; uint8_t end_cmd; int ack_size; uint8_t ack[0]; }bootinfo_def; // 自检完成 static void bootinfo_end(ucport_def *u,port_mcu *src,void *data,int ack,char *err_str) { bootinfo_def *w=(bootinfo_def *)u; uint8_t addr=port_get_addr(src); if(addr<=0||addr>w->slave_num){ DBG_WARN("addr err:%d",addr); return; } uint8_t *d=&w->ack[sizeof(local_bootinfo)+sizeof(bootinfo_data)*(addr-1)]; if(data){ memcpy(d,data,sizeof(bootinfo_data)); } w->ack_num++; if(w->ack_num>=w->slave_num) { array_def *a=arr_creat(); if(strcmp(sys_param()->device_type,"coder")==0) { // 赋码仪添加通道数 arr_append(a,w->slave_num); } arr_append(a,0); arr_appends(a,w->ack,w->ack_size); emit tran_send_signal(w->u.p,w->end_cmd,arr_temp(a)); tran_set_busy(w->u.p,0); } } static void bootinfo_del(ucport_def *u) { free(u); } // 填充本机自检信息 static void bootinfo_fill_local(uint8_t *d) { int tick=rt_tick_get()/1000; uint8_t wdog=bk_wdog_fun()?1:0; tran_def *t=app_variable("tran",0,0); uint32_t temp32=0; uint16_t temp16=0; uint8_t temp8=0; memcpy(d,BUILD_DATE,strlen(BUILD_DATE)+1);d+=20; memcpy(d,SOFT_VERSION,strlen(SOFT_VERSION)+1);d+=8; memcpy(d,&tick,4);d+=4; memcpy(d,&wdog,1);d+=1; memcpy(d,sys_param()->device_type,12);d+=12; memcpy(d,sys_param()->local_ip,4);d+=4; memcpy(d,sys_param()->host_ip,4);d+=4; temp16=sys_param()->host_port; memcpy(d,&temp16,2);d+=2; temp8=sys_param()->local_id; memcpy(d,&temp8,1);d+=1; temp32=check_scheme()->plan_id; memcpy(d,&temp32,4);d+=4; if(t){ uint32_t temp32=tran_get_slave_online(t); memcpy(d,&temp32,4);d+=4; }else { memset(d,0,4);d+=4; } } static ucport_def *bootinfo_self(tran_def *t, int slave_num,uint8_t cmd,array_def *data) { int return_size=sizeof(local_bootinfo)+sizeof(bootinfo_data)*slave_num; bootinfo_def *u=calloc(1,sizeof(bootinfo_def)+return_size); u->ack_size=return_size; u->slave_num=slave_num; u->u.p=t; u->u.del=bootinfo_del; u->u.doend=bootinfo_end; tran_set_busy(t,1); bootinfo_fill_local(u->ack); for(int i=0;iu.p,i); // 这里打开检测 if(mcu){ port_start(mcu,bootinfo_creat()); } } array_def *a=arr_creat(); if(strcmp(sys_param()->device_type,"coder")==0) { // 赋码仪添加通道数 arr_append(a,10); } arr_append(a,0); emit tran_reply_signal(u->u.p,arr_temp(a)); return (ucport_def *)u; } static ucport_def *bootinfo_coder(tran_def *t,uint8_t cmd,array_def *data) { // 对于赋码仪,从机个数为10 bootinfo_def *u=(bootinfo_def *)bootinfo_self(t,10,cmd,data); u->end_cmd=0x84; return (ucport_def *)u; } static ucport_def *bootinfo_checker(tran_def *t,uint8_t cmd,array_def *data) { // 对于批检仪,从机个数为20 bootinfo_def *u=(bootinfo_def *)bootinfo_self(t,20,cmd,data); u->end_cmd=0x35; return (ucport_def *)u; } transmit_export(ym_checker,0x34,bootinfo_checker) transmit_export(ym_checker,0x04,bootinfo_coder) __packed typedef struct{ char devicetype[12]; char hostif[8]; uint8_t localip[4]; uint8_t hostip[4]; uint16_t hostport; uint8_t localid; int uartbsp; uint8_t coder_return_mode; uint8_t slave_addr_start; }paraminfo_def; typedef struct{ ucport_def u; paraminfo_def par; }param_def; static void param_del(ucport_def *u) { free(u); } // 填充配置项 static void paraminfo_fill(paraminfo_def *p) { memcpy(p->devicetype,sys_param()->device_type,12); memcpy(p->hostif,sys_param()->host_if,8); memcpy(p->localip,sys_param()->local_ip,4); memcpy(p->hostip,sys_param()->host_ip,4); p->hostport=sys_param()->host_port; p->localid=sys_param()->local_id; p->uartbsp=sys_param()->uartbsp; p->coder_return_mode=sys_param()->coder_ret_mode; p->slave_addr_start=sys_param()->slave_addr_start; } // 保存配置项 static int paraminfo_save(paraminfo_def *p) { int ret=0; sys_param_def *spar=0; spar=calloc(1,sizeof(sys_param_def)); memcpy(spar,sys_param(),sizeof(sys_param_def)); if(strcmp("coder",p->devicetype)==0||strcmp("checker",p->devicetype)==0) memcpy(spar->device_type,p->devicetype,12); else { DBG_WARN("devicetype param must be \"coder\" or \"checker\""); ret=1;return ret;} if(strcmp("uart4",p->hostif)==0||strcmp("utcp",p->hostif)==0) memcpy(spar->host_if,p->hostif,8); else { DBG_WARN("host_if param must be \"uart4\" or \"utcp\""); ret=2;return ret;} if(memcmp(p->localip,(uint8_t []){0,0,0,0},4)!=0) memcpy(spar->local_ip,p->localip,4); else { DBG_WARN("localip param must not be all zero"); ret=3;return ret;} if(memcmp(p->hostip,(uint8_t []){0,0,0,0},4)!=0) memcpy(spar->host_ip,p->hostip,4); else { DBG_WARN("hostip param must not be all zero"); ret=4;return ret;} spar->host_port=p->hostport; spar->local_id=p->localid; if(p->uartbsp==115200||p->uartbsp==9600) spar->uartbsp=p->uartbsp; else { DBG_WARN("uartbsp param must be 115200 or 9600"); ret=5;return ret;} if(p->coder_return_mode==0||p->coder_return_mode==1) spar->coder_ret_mode=p->coder_return_mode; else { DBG_WARN("coder_return_mode param must be 0 or 1"); ret=6;return ret;} if(p->slave_addr_start==0||p->slave_addr_start==1) spar->slave_addr_start=p->slave_addr_start; else { DBG_WARN("slave_addr_start param must be 0 or 1"); ret=7;return ret;} flash_save_param(spar); return ret; } static ucport_def *param(tran_def *t, uint8_t cmd,array_def *data) { if(arr_length(data)<1){ DBG_WARN("cmd format err."); return 0; } int off=0; param_def *u=calloc(1,sizeof(param_def)); u->u.p=t; u->u.del=param_del; if(strcmp(sys_param()->device_type,"coder")==0) { // 赋码仪要忽略通道数参数 off=1; } uint8_t op=arr_get(data,off); // 1是写,0是读 if(op==0) { paraminfo_fill(&u->par); uint8_t *d=(uint8_t *)(&u->par); array_def *a=arr_creat(); if(strcmp(sys_param()->device_type,"coder")==0) { // 赋码仪添加通道数 arr_append(a,10); } arr_append(a,0); arr_appends(a,d,sizeof(paraminfo_def)); emit tran_reply_signal(u->u.p,arr_temp(a)); }else if(op==1) { array_def *a=arr_creat(); if(strcmp(sys_param()->device_type,"coder")==0) { // 赋码仪添加通道数 arr_append(a,10); } if(arr_length(data)<1+off+sizeof(paraminfo_def)){ arr_append(a,0xff); emit tran_reply_signal(u->u.p,arr_temp(a)); }else{ memcpy(&u->par,arr_data(data)+1,sizeof(paraminfo_def)); int ret=paraminfo_save(&u->par); arr_append(a,ret); emit tran_reply_signal(u->u.p,arr_temp(a)); } } return (ucport_def *)u; } transmit_export(ym_checker,0x08,param)