Files
checker_host/prot_cmd/cmd_pc.cpp
ranchuan cc5b1b7458 广播命令已接收的回复不再触发回调
检测命令0x0c只能使用单播方式,广播方式因为不能即时回复停止信号,回复会出错
  添加电阻测试命令,添加自检命令
2023-12-13 18:29:46 +08:00

812 lines
18 KiB
C++

#include "cmd_pc.h"
#include "cmd_slave.h"
#include "prot/prot_m4.h"
#include "prot/prot_pc.h"
#include "prot/prot_slave.h"
#include "base/mycfg.h"
#include "base/check_cfg.h"
#include "QDebug"
#include "elec/elec_judge.h"
typedef struct
{
int moter_count;
int moter_run;
} moter_def;
static moter_def g_moter;
// 电机控制
myarray moter_ctrl(myarray op)
{
mycfg *cfg_ = syscfg();
moter_def *moter = &g_moter;
myarray r;
if (op == "up")
{
int count = 0;
if (moter->moter_count > 0)
{
moter->moter_run = 1;
count = -moter->moter_count - 100;
moter->moter_count = 0;
mystring s = mystring("moter %1").arg(count);
r = myarray(s.data());
}
else
{
qWarning("moter count out of range.");
return r;
}
}
else if (op == "down")
{
int count = 0;
if (moter->moter_count < cfg_->moter_count)
{
moter->moter_run = 1;
count = cfg_->moter_count - moter->moter_count;
moter->moter_count += count;
mystring s = mystring("moter %1").arg(count);
r = myarray(s.data());
qDebug("moter down:%s",s.data());
}
else
{
qWarning("moter count out of range.") ;
return r;
}
}
qDebug("moter ctrl:%s",op.data());
return r;
}
// 自研批检仪检测
int selfdev_check::dolater(int cmd, myarray data)
{
prot_m4 *m4 = protM4();
prot_slave *slave=protSlave();
mycfg *cfg=syscfg();
busy=1;
connect(this, &selfdev_check::send_to_m4_signal, m4, &prot_m4::send_data_slot);
moter_down_cb_fun=[=](myarray data)
{
m4->del_irq_fun(moter_down_cb_fun,"moter down");
{
// 这里开始检测
qDebug("start check.");
emit send_data_signal(cmd,myarray(1,0));
QList<int> addrs=cfg->calc_slave_addrs();
foreach(int addr, addrs){
HandleSlave *s=new slave_check();
bool ack=slave->set_slave_handle(addr,s);
if(ack==false){
qWarning("addr %d handle is busy.",addr);
}else{
connect(s,&HandleSlave::end_signal,this,&selfdev_check::slave_end_slot);
s->start(myarray());
}
}
}
};
myarray moter_cmd=moter_ctrl("down");
if(moter_cmd.size()==0){
busy=0;
qWarning("moter failed.");
}else{
m4->set_irq_fun(moter_down_cb_fun,"moter down");
emit send_to_m4_signal(moter_cmd);
}
slave_acked.clear();
for(int i=0;i<cfg->slave_num;i++){
slave_acked.append(myarray());
}
slave_acked_num=0;
return 0;
}
void selfdev_check::timeout()
{
busy=0;
}
// 把小板的返回数据转化为自研批检仪上位机的格式
static myarray tran_slave_to_selfdev_check(myarray &data)
{
check_cfg *ccfg_=check_plan();
// 返回值个数
int return_num=ccfg_->get_return_num();
// 参数错误字节数
int paramerr_num=(return_num+7)/8;
// 每个通道占用的长度
int len_for_each=1+8+paramerr_num+return_num*2;
// 去掉应答位
data.remove(0,1);
myarray r;
if(data.size()<17){
r.append(char(208));
r.append((len_for_each-1),char(0xff));
}else{
myarray paramerr=ccfg_->returns_to_paramerr(data.right(return_num*2));
r=data.left(8)+paramerr+data.right(return_num*2);
uint8_t marerr=0,suberr=0;
uint8_t *d=(uint8_t *)data.data();
elec_judge(ccfg_->check_scheme(),ccfg_->get_check_task_num(),
d,d+8,d+16,&marerr,&suberr);
r.insert(0,uint8_t(marerr));
}
return r;
}
void selfdev_check::slave_end_slot(int addr,int ack, myarray data)
{
if(addr<=0||addr>slave_acked.size()){
qWarning("slave addr err:%d",addr);
return;
}
slave_acked.replace(addr-1,data);
slave_acked_num++;
if(slave_acked_num>=slave_acked.size()){
myarray r;
r.append(char(0));
for(int i=0;i<slave_acked.size();i++){
r.append(tran_slave_to_selfdev_check(slave_acked[i]));
}
emit send_data_signal(0x31,r);
busy=0;
}
}
static HandlePc *get_selfdev_check(){
return new selfdev_check();
}
protpc_export(0x30, get_selfdev_check);
// 自研批检仪检测
int selfdev_check2::dolater(int cmd, myarray data)
{
prot_m4 *m4 = protM4();
prot_slave *slave=protSlave();
mycfg *cfg=syscfg();
busy=1;
connect(this, &selfdev_check2::send_to_m4_signal, m4, &prot_m4::send_data_slot);
moter_down_cb_fun=[=](myarray data)
{
m4->del_irq_fun(moter_down_cb_fun,"moter down");
{
// 这里开始检测
qDebug("start check.");
emit send_data_signal(cmd,myarray(1,0));
QList<int> addrs=cfg->calc_slave_addrs();
HandleBoardCast *s=new slave_check2();
bool ack=slave->set_boardcast_handle(addrs,s);
if(ack==false){
qWarning("handle is busy.");
}else{
connect(s,&HandleBoardCast::end_signal,this,&selfdev_check2::slave_end_slot);
s->start(myarray());
}
}
};
myarray moter_cmd=moter_ctrl("down");
if(moter_cmd.size()==0){
busy=0;
qWarning("moter failed.");
}else{
m4->set_irq_fun(moter_down_cb_fun,"moter down");
emit send_to_m4_signal(moter_cmd);
}
slave_acked.clear();
for(int i=0;i<cfg->slave_num;i++){
slave_acked.append(myarray());
}
slave_acked_num=0;
return 0;
}
void selfdev_check2::timeout()
{
busy=0;
}
void selfdev_check2::slave_end_slot(int addr,int ack, slave_data data)
{
for(int i=0;i<data.size();i++){
slave_ret slave=data.at(i);
slave_acked.replace(slave.addr-1,slave.data);
slave_acked_num++;
}
myarray r;
r.append(char(0));
for(int i=0;i<slave_acked.size();i++){
r.append(tran_slave_to_selfdev_check(slave_acked[i]));
}
emit send_data_signal(0x31,r);
busy=0;
}
//static HandlePc *get_selfdev_check2(){
// return new selfdev_check2();
//}
//protpc_export(0x30, get_selfdev_check2);
// 检测结束 电机上升
int selfdev_checkend::dolater(int cmd, myarray data)
{
prot_m4 *m4 = protM4();
connect(this, &selfdev_checkend::send_to_m4_signal, m4, &prot_m4::send_data_slot);
emit send_to_m4_signal(moter_ctrl("up"));
return 0;
}
void selfdev_checkend::timeout(){
}
static HandlePc *get_selfdev_checkend(){
return new selfdev_checkend();
}
protpc_export(0x31, get_selfdev_checkend);
// 电机控制
int selfdev_moter::dolater(int cmd, myarray data)
{
prot_m4 *m4 = protM4();
mycfg *cfg_=syscfg();
connect(this, &selfdev_moter::send_to_m4_signal, m4, &prot_m4::send_data_slot);
if(data[0]==0x02){
emit send_to_m4_signal(moter_ctrl("up"));
}else if(data[0]==0x03){
emit send_to_m4_signal(moter_ctrl("down"));
}else if(data[0]==0x01){
if(data.size()>=3){
int count=(data[1])|(data[2]<<8);
cfg_->moter_count=20000+count;
qDebug("moter count=%d",cfg_->moter_count);
cfg_->save();
}
}
emit send_data_signal(0x40,myarray(1,char(0)));
return 0;
}
void selfdev_moter::timeout(){
}
static HandlePc *get_selfdev_moter(){
return new selfdev_moter();
}
protpc_export(0x40, get_selfdev_moter);
// 从机升级
int selfdev_slaveupdate::dolater(int cmd, myarray data)
{
myarray r;
int len_filename=data[0];
mystring name=data.mid(1,len_filename);
prot_slave *slave=protSlave();
mycfg *cfg_=syscfg();
busy=1;
qInfo()<<"slave_app name:"<<name<<endl;
data.remove(0,len_filename+1);
// TODO 校验小板程序
r.append(uint8_t(0));
cfg_->save_file(name,data);
emit send_data_signal(0xfe,myarray(1,char(0)));
// 自动给小板升级
// start_updata_mcu(cfg_->config_path+name,slave_addrs);
HandleBoardCast *b=new boardcast_updata();
bool ack=slave->set_boardcast_handle(cfg_->calc_slave_addrs(),b);
if(ack==false){
qWarning("handle is busy.");
busy=0;
}else{
connect(b,&HandleBoardCast::end_signal,this,&selfdev_slaveupdate::slave_end_slot);
b->start(data);
}
return 0;
}
void selfdev_slaveupdate::timeout(){
busy=0;
qDebug("slave update timeout");
}
void selfdev_slaveupdate::slave_end_slot(int addr,int ack, slave_data data)
{
qDebug("slave update end,ack=%s",ack?"failed":"success");
busy=0;
}
static HandlePc *get_selfdev_slaveupdate(){
return new selfdev_slaveupdate();
}
protpc_export(0xfe, get_selfdev_slaveupdate);
// 方案升级
int selfdev_update_scheme::dolater(int cmd, myarray data)
{
myarray r;
int len_filename=data[0];
mystring name=data.mid(1,len_filename);
prot_slave *slave=protSlave();
mycfg *cfg_=syscfg();
check_cfg *ccfg_=check_plan();
uint8_t rw=data[0];
data.remove(0,1);
busy=1;
if(rw==0)
{
// 读方案
r.append(char(0));
r.append(rw);
r.append(ccfg_->scheme_to_jstring());
emit send_data_signal(0x22,r);
busy=0;
}
else
{
// 写方案
bool ack=ccfg_->updata(QString(data));
r.append(ack?char(0):char(1));
r.append(rw);
if(ack){
// 检测数据保存
// if(comm_f_!=nullptr){
// delete comm_f_;
// comm_f_=nullptr;
// }
// 自动给小板升级
HandleBoardCast *b=new boardcast_updata_scheme();
bool ack=slave->set_boardcast_handle(cfg_->calc_slave_addrs(),b);
if(ack==false){
qWarning("handle is busy.");
busy=0;
}else{
connect(b,&HandleBoardCast::end_signal,this,&selfdev_update_scheme::slave_end_slot);
myarray scheme=myarray((const char *)ccfg_->check_scheme(),ccfg_->check_scheme_size());
b->start(scheme);
}
}
else{
r.append("方案解析失败");
qWarning("scheme check failed.");
}
emit send_data_signal(0x22,r);
}
return 0;
}
void selfdev_update_scheme::timeout(){
busy=0;
qDebug("slave update timeout");
}
void selfdev_update_scheme::slave_end_slot(int addr,int ack, slave_data data)
{
qDebug("slave update end,ack=%s",ack?"failed":"success");
busy=0;
}
static HandlePc *get_selfdev_update_scheme(){
return new selfdev_update_scheme();
}
protpc_export(0x22, get_selfdev_update_scheme);
// 本机升级
int selfdev_hostupdate::dolater(int cmd, myarray data)
{
myarray r;
int len_filename=data[0];
mystring name=data.mid(1,len_filename);
prot_slave *slave=protSlave();
mycfg *cfg_=syscfg();
busy=1;
qInfo()<<"host_app name:"<<name<<endl;
data.remove(0,len_filename+1);
// TODO 校验主板程序
r.append(uint8_t(0));
cfg_->save_file(name,data);
emit send_data_signal(0xfd,myarray(1,char(0)));
return 0;
}
static HandlePc *get_selfdev_hostupdata(){
return new selfdev_hostupdate();
}
protpc_export(0xfd, get_selfdev_hostupdata);
// jwt升级
int selfdev_jwtupdate::dolater(int cmd, myarray data)
{
myarray r;
int len_filename=data[0];
mystring name=data.mid(1,len_filename);
prot_slave *slave=protSlave();
mycfg *cfg_=syscfg();
busy=1;
qInfo()<<"jwt_app name:"<<name<<endl;
data.remove(0,len_filename+1);
// TODO 校验小板程序
r.append(uint8_t(0));
cfg_->save_file(name,data);
emit send_data_signal(0xfe,myarray(1,char(0)));
// 自动给小板升级
// start_updata_mcu(cfg_->config_path+name,slave_addrs);
HandleBoardCast *b=new boardcast_updata_jwt();
bool ack=slave->set_boardcast_handle(cfg_->calc_slave_addrs(),b);
if(ack==false){
qWarning("handle is busy.");
busy=0;
}else{
connect(b,&HandleBoardCast::end_signal,this,&selfdev_slaveupdate::slave_end_slot);
b->start(data);
}
return 0;
}
static HandlePc *get_selfdev_jwtupdate(){
return new selfdev_jwtupdate();
}
protpc_export(0x27, get_selfdev_jwtupdate);
// 自研批检仪自检
int selfdev_bootinfo::dolater(int cmd, myarray data)
{
prot_slave *slave=protSlave();
mycfg *cfg_=syscfg();
busy=1;
// 这里开始检测
qDebug("get bootinfo.");
emit send_data_signal(cmd,myarray(1,0));
HandleBoardCast *b=new slave_cmd();
bool ack=slave->set_boardcast_handle(cfg_->calc_slave_addrs(),b);
if(ack==false){
qWarning("handle is busy.");
busy=0;
}else{
connect(b,&HandleBoardCast::end_signal,this,&selfdev_bootinfo::slave_end_slot);
b->cmd=0x13;
b->start(data);
}
slave_acked.clear();
for(int i=0;i<cfg_->slave_num;i++){
slave_acked.append(myarray());
}
slave_acked_num=0;
return 0;
}
void selfdev_bootinfo::timeout()
{
busy=0;
}
#pragma pack(1)
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;
#pragma pack()
#pragma pack(1)
typedef struct{
uint8_t app_state;
uint8_t slaver_addr;
uint16_t chip_tmper;
uint16_t ad_2v5;
uint16_t ad_1v25;
uint16_t ad_wave;
uint16_t ad_5v5_just;
uint16_t ad_26v_just;
uint16_t hard_version;
uint16_t soft_version;
uint16_t res_just;
uint32_t scheme_id;
}bootinfo_data;
#pragma pack()
// 填充本机自检信息
myarray bootinfo_fill_local(void)
{
int tick=-1;
uint8_t wdog=0;
uint32_t temp32=0;
uint16_t temp16=0;
uint8_t temp8=0;
uint8_t ip[4]={0};
QStringList iplist;
mycfg *cfg_=syscfg();
check_cfg *ccfg_=check_plan();
uint8_t *d=(uint8_t *)calloc(1,sizeof(local_bootinfo)+1);
uint8_t *d_free=d;
memcpy(d,cfg_->build_date.data(),cfg_->build_date.size()+1);d+=20;
memcpy(d,cfg_->soft_version.data(),cfg_->soft_version.size()+1);d+=8;
memcpy(d,&tick,4);d+=4;
memcpy(d,&wdog,1);d+=1;
memcpy(d,cfg_->device_type.data(),cfg_->device_type.size()+1);d+=12;
iplist=cfg_->local_ip.split('.');
ip[0]=iplist[0].toInt();
ip[1]=iplist[1].toInt();
ip[2]=iplist[2].toInt();
ip[3]=iplist[3].toInt();
memcpy(d,ip,4);d+=4;
iplist=cfg_->server_ip.split('.');
ip[0]=iplist[0].toInt();
ip[1]=iplist[1].toInt();
ip[2]=iplist[2].toInt();
ip[3]=iplist[3].toInt();
memcpy(d,ip,4);d+=4;
temp16=cfg_->server_port;
memcpy(d,&temp16,2);d+=2;
temp8=cfg_->local_id;
memcpy(d,&temp8,1);d+=1;
temp32=ccfg_->get_plan_id();
memcpy(d,&temp32,4);d+=4;
temp32=0;
for(int i=0;i<cfg_->slave_num;i++){
temp32|=1<<i;
}
memcpy(d,&temp32,4);d+=4;
myarray arry((char *)d_free,sizeof(local_bootinfo));
free(d_free);
qDebug()<<"local data="<<arry.toHex(' ');
return arry;
}
static myarray slave_to_bootinfo_byte(myarray data){
data.remove(0,1);
int size_slave=sizeof(bootinfo_data);
int data_size=data.size();
if(size_slave>data_size){
data.append(size_slave-data_size,0);
}
return data;
}
void selfdev_bootinfo::slave_end_slot(int addr,int ack, slave_data data)
{
qDebug("selfdev get bootinfo end.");
myarray r;
r.append(char(0));
r+=bootinfo_fill_local();
for(int i=0;i<data.size();i++){
slave_ret slave=data.at(i);
slave_acked.replace(slave.addr-1,slave.data);
slave_acked_num++;
}
for(int i=0;i<slave_acked.size();i++){
r.append(slave_to_bootinfo_byte(slave_acked[i]));
}
emit send_data_signal(0x35,r);
busy=0;
}
static HandlePc *get_selfdev_bootinfo(){
return new selfdev_bootinfo();
}
protpc_export(0x34, get_selfdev_bootinfo);
// 测量电阻
int selfdev_measure_rescv::dolater(int cmd, myarray data)
{
prot_m4 *m4 = protM4();
prot_slave *slave=protSlave();
mycfg *cfg=syscfg();
busy=1;
connect(this, &selfdev_measure_rescv::send_to_m4_signal, m4, &prot_m4::send_data_slot);
moter_down_cb_fun=[=](myarray data)
{
m4->del_irq_fun(moter_down_cb_fun,"moter down");
{
// 这里开始检测
qDebug("start check.");
QList<int> addrs=cfg->calc_slave_addrs();
HandleBoardCast *s=new slave_cmd();
bool ack=slave->set_boardcast_handle(addrs,s);
if(ack==false){
qWarning("handle is busy.");
}else{
connect(s,&HandleBoardCast::end_signal,this,&selfdev_measure_rescv::slave_end_slot);
s->cmd=0x05;
s->start(data);
}
}
};
myarray moter_cmd=moter_ctrl("down");
if(moter_cmd.size()==0){
busy=0;
qWarning("moter failed.");
}else{
m4->set_irq_fun(moter_down_cb_fun,"moter down");
emit send_to_m4_signal(moter_cmd);
}
slave_acked.clear();
for(int i=0;i<cfg->slave_num;i++){
slave_acked.append(myarray());
}
slave_acked_num=0;
return 0;
}
void selfdev_measure_rescv::timeout()
{
busy=0;
}
void selfdev_measure_rescv::slave_end_slot(int addr,int ack, slave_data data)
{
qDebug("selfdev measure_rescv end.");
emit send_to_m4_signal(moter_ctrl("up"));
myarray r;
r.append(char(0));
for(int i=0;i<data.size();i++){
slave_ret slave=data.at(i);
slave_acked.replace(slave.addr-1,slave.data);
slave_acked_num++;
}
for(int i=0;i<slave_acked.size();i++){
r.append(char(i+1));
r.append(slave_acked[i].right(2));
}
QTimer::singleShot(0, this, [=](){
emit send_data_signal(0x42,r);
});
busy=0;
}
static HandlePc *get_selfdev_measure_rescv(){
return new selfdev_measure_rescv();
}
protpc_export(0x42, get_selfdev_measure_rescv);
// 设置电阻校准
int selfdev_set_rescv::dolater(int cmd, myarray data)
{
prot_slave *slave=protSlave();
mycfg *cfg_=syscfg();
busy=1;
// 这里开始检测
qDebug("set_rescv.");
emit send_data_signal(cmd,myarray(1,0));
HandleBoardCast *b=new slave_cmd();
bool ack=slave->set_boardcast_handle(cfg_->calc_slave_addrs(),b);
if(ack==false){
qWarning("handle is busy.");
busy=0;
}else{
connect(b,&HandleBoardCast::end_signal,this,&selfdev_set_rescv::slave_end_slot);
// 广播设置校准值,需使用新增命令
b->cmd=0x13;
b->start(data);
}
slave_acked.clear();
for(int i=0;i<cfg_->slave_num;i++){
slave_acked.append(myarray());
}
slave_acked_num=0;
return 0;
}
void selfdev_set_rescv::timeout()
{
busy=0;
}
void selfdev_set_rescv::slave_end_slot(int addr,int ack, slave_data data)
{
qDebug("selfdev set_rescv end.");
myarray r;
r.append(char(0));
emit send_data_signal(0x41,r);
busy=0;
}
static HandlePc *get_selfdev_set_rescv(){
return new selfdev_set_rescv();
}
protpc_export(0x41, get_selfdev_set_rescv);