Files
checker_slave/source/task/tran_for_checker.c
2023-06-15 18:11:28 +08:00

402 lines
8.2 KiB
C

#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;
uint16_t addrs;
void (*doexert)(ucport_def *u);
uint8_t ack_num;
uint8_t ack_size;
uint8_t ack[0];
}check_def;
// 检测完成
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>10){
DBG_WARN("addr err:%d",addr);
return;
}
int return_size=(check_scheme()->range_num*2+8);
uint8_t *ack_d=&w->ack[(addr-1)*return_size];
if(return_size!=arr_length(data)){
DBG_WARN("data err:%d",addr);
return;
}
memcpy(ack_d,arr_data(data),return_size);
// TODO: 还有4字节数据
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)
{
if(arr_length(data)<7){
DBG_WARN("cmd format err.");
return 0;
}
int return_size=(check_scheme()->range_num*2+8);
check_def *u=calloc(1,sizeof(check_def)+return_size*10);
u->ack_size=return_size*10;
u->u.p=t;
u->u.del=check_del;
u->u.doend=check_end;
tran_set_busy(t,1);
for(int i=0;i<20;i++)
{
if(u->addrs&(1<<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;i<slave_num;i++)
{
port_mcu *mcu=tran_get_portm(u->u.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 void paraminfo_save(paraminfo_def *p)
{
sys_param_def *spar=0;
spar=calloc(1,sizeof(sys_param_def));
memcpy(spar,sys_param(),sizeof(sys_param_def));
memcpy(spar->device_type,p->devicetype,12);
memcpy(spar->host_if,p->hostif,8);
memcpy(spar->local_ip,p->localip,4);
memcpy(spar->host_ip,p->hostip,4);
spar->host_port=p->hostport;
spar->local_id=p->localid;
spar->uartbsp=p->uartbsp;
spar->coder_ret_mode=p->coder_return_mode;
spar->slave_addr_start=p->slave_addr_start;
flash_save_param(spar);
}
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+sizeof(paraminfo_def)){
arr_append(a,1);
emit tran_reply_signal(u->u.p,arr_temp(a));
}else{
memcpy(&u->par,arr_data(data)+1,sizeof(paraminfo_def));
paraminfo_save(&u->par);
arr_append(a,0);
emit tran_reply_signal(u->u.p,arr_temp(a));
}
paraminfo_save(&u->par);
}
return (ucport_def *)u;
}
transmit_export(ym_checker,0x08,param)