添加广播方式升级

This commit is contained in:
ranchuan
2023-11-29 15:36:45 +08:00
parent a0b0f41c39
commit e34b8111dc
30 changed files with 1388 additions and 146 deletions

View File

@@ -5,16 +5,25 @@ void prot_m4::init()
{
if_ = interFaceFind("uart_m4");
codec_ = codecFind("codec_m4");
if(if_==nullptr||codec_==nullptr){
return;
}
if_->set_irq([=](myarray recv)
{
if(codec_->packCheck(recv_data)==true){
int cmd,src,dst;
myarray data=codec_->decode(src,dst,cmd,recv_data);
if(exe_cb_fun(data)==false){
qWarning("can not find cb fun with:\"%s\"",data.data());
}
recv_data.clear();
recv_data+=recv;
int pack_len=0;
while(pack_len=codec_->packCheck(recv_data),pack_len>0){
int cmd,src,dst;
myarray data=codec_->decode(src,dst,cmd,recv_data);
recv_data.remove(0,pack_len);
if(wait>0) wait--;
if(exe_cb_fun(data)==false){
qWarning("can not find cb fun with:\"%s\"",data.data());
}
if(send_list.size()>0){
if_->write(send_list.takeFirst());
wait+=2;
}
}
});
}
@@ -24,7 +33,12 @@ void prot_m4::send_data_slot(myarray data)
if ((if_ != nullptr) && (codec_ != nullptr))
{
myarray send = codec_->encode(0, 0, 0, data);
if_->write(send);
send_list.append(send);
if(wait==0){
wait+=2;
qDebug("send m4:%s",data.data());
if_->write(send_list.takeFirst());
}
}
}
@@ -33,13 +47,16 @@ bool prot_m4::exe_cb_fun(myarray data)
int left;
for (int i = 0; i < funs.size(); i++)
{
left = funs[i].cmd.size();
// 这里size包含结尾符要去掉
left = funs[i].cmd.size()-1;
if (data.left(left) == funs[i].cmd)
{
if (funs[i].fun != nullptr)
{
funs[i].fun(data.mid(left));
return true;
for(int j=0;j<funs[i].funs.size();j++){
prot_m4_cb fun=funs[i].funs[j];
if(fun!=nullptr){
fun(data.mid(left));
return true;
}
}
}
}
@@ -65,12 +82,21 @@ bool prot_m4::set_irq_fun(prot_m4_cb fun, myarray data)
left = funs[i].cmd.size();
if (data.left(left) == funs[i].cmd)
{
return false;
for(int j=0;j<funs[i].funs.size();j++){
prot_m4_cb temp=funs[i].funs[j];
if(fun.target<void(*)(myarray data)>()==temp.target<void(*)(myarray data)>()){
qDebug("this function pointer was exited.");
return false;
}
}
qDebug("add function pointer success.");
funs[i].funs.append(fun);
return true;
}
}
HandleM4_def m4_cmd;
m4_cmd.cmd = data;
m4_cmd.fun = fun;
m4_cmd.funs.append(fun);
funs.append(m4_cmd);
return true;
}
@@ -83,8 +109,24 @@ bool prot_m4::del_irq_fun(prot_m4_cb fun, myarray data)
left = funs[i].cmd.size();
if (data.left(left) == funs[i].cmd)
{
funs.removeAt(i);
return true;
if(fun==nullptr){
qDebug("del the same string cb.");
funs.removeAt(i);
return true;
}else{
for(int j=0;j<funs[i].funs.size();j++){
prot_m4_cb temp=funs[i].funs[j];
if(fun.target<void(*)(myarray data)>()==temp.target<void(*)(myarray data)>()){
qDebug("del the same function pointer.");
funs[i].funs.removeAt(j);
if(funs[i].funs.size()==0){
funs.removeAt(i);
}
return true;
}
}
return false;
}
}
}
return false;

View File

@@ -16,14 +16,14 @@ typedef std::function<void(myarray data)> prot_m4_cb;
typedef struct
{
prot_m4_cb fun;
QList<prot_m4_cb> funs;
myarray cmd;
} HandleM4_def;
class prot_m4 : public QObject
{
public:
prot_m4() { if_ = nullptr; }
prot_m4() { if_ = nullptr;wait=0; }
~prot_m4() {}
void init();
bool set_irq_fun(prot_m4_cb fun, myarray data);
@@ -40,6 +40,8 @@ protected:
Codec *codec_;
QThread thread;
myarray recv_data;
int wait;
QList<myarray> send_list;
};
prot_m4 *protM4();

View File

@@ -25,30 +25,35 @@ HandlePc *handlePcFind(int cmd)
void ProtPc::init()
{
if_ = interFaceFind("tcp");
if_ = interFaceFind("uart_host");
codec_ = codecFind("codec_ym");
if(if_==nullptr||codec_==nullptr){
return;
}
if_->set_irq([=](myarray recv)
{
recv_data+=recv;
if(codec_->packCheck(recv_data)==true){
int cmd,src,dst;
myarray data=codec_->decode(src,dst,cmd,recv_data);
if(handle_!=nullptr){
if(handle_->busy==0){
disconnect(handle_,&HandlePc::send_data_signal,this,&ProtPc::send_data_slot);
delete handle_;
}else{
qWarning("prot_pc is busy.");
return;
}
int pack_len=0;
while(pack_len=codec_->packCheck(recv_data),pack_len>0){
int cmd,src,dst;
qDebug("host recv:%s",recv_data.toHex(' ').data());
myarray data=codec_->decode(src,dst,cmd,recv_data);
recv_data.remove(0,pack_len);
if(handle_!=nullptr){
if(handle_->busy==0){
disconnect(handle_,&HandlePc::send_data_signal,this,&ProtPc::send_data_slot);
delete handle_;
}else{
qWarning("prot_pc is busy.");
return;
}
handle_=handlePcFind(cmd);
if(handle_!=nullptr){
connect(handle_,&HandlePc::send_data_signal,this,&ProtPc::send_data_slot);
handle_->dolater(cmd,data);
}
recv_data.clear();
}
handle_=handlePcFind(cmd);
if(handle_!=nullptr){
connect(handle_,&HandlePc::send_data_signal,this,&ProtPc::send_data_slot);
handle_->dolater(cmd,data);
}
}
});
}

View File

@@ -80,7 +80,7 @@ typedef struct
} handlepc_def;
#define protpc_export(cmd_, fun_) \
__attribute__((used)) static handlepc_def _handlepc_##name_ __attribute__((section("protpc"))) = { \
__attribute__((used)) static handlepc_def _handlepc_##cmd_ __attribute__((section("protpc"))) = { \
.cmd = cmd_, \
.handle_get_fun = fun_, \
}

View File

@@ -6,26 +6,36 @@ void prot_slave::init()
if_ = interFaceFind("can");
codec_ = codecFind("codec_slave");
mycfg *cfg_ = syscfg();
if(if_==nullptr||codec_==nullptr){
return;
}
for (int i = 0; i < cfg_->slave_num; i++)
{
slaves.append(nullptr);
}
if_->set_irq([=](myarray recv)
{
if(codec_->packCheck(recv)==true){
int cmd,src,dst;
HandleSlave *handle=nullptr;
myarray data=codec_->decode(src,dst,cmd,recv);
if((src>slaves.size())||(src<=0)){
qWarning("slave addr err:%d",src);
int pack_len=0;
if(pack_len=codec_->packCheck(recv),pack_len>0){
int cmd,src,dst;
HandleSlave *handle=nullptr;
myarray data=codec_->decode(src,dst,cmd,recv);
if((src>slaves.size())||(src<=0)){
qWarning("slave addr err:%d",src);
}else{
if((broadcast_!=nullptr)&&(broadcast_->busy)){
broadcast_->addr_response|=1<<(src-1);
if(broadcast_->check_response()==true)
broadcast_->dolater(cmd,data);
}else{
handle=slaves[src-1];
if(handle!=nullptr){
handle->dolater(cmd,data);
}else{
qWarning("slave addr=%d not have handle.",src);
}
handle=slaves[src-1];
if(handle!=nullptr){
handle->dolater(cmd,data);
}else{
qWarning("slave addr=%d not have handle.",src);
}
}
}
}
});
}
@@ -51,17 +61,38 @@ bool prot_slave::set_slave_handle(int addr, HandleSlave *handle)
delete temp;
}
}
handle->addr=addr;
connect(handle, &HandleSlave::send_data_signal, this, &prot_slave::send_data_slot);
slaves.replace(addr - 1, handle);
return true;
}
bool prot_slave::set_boardcast_handle(QList<int> addrs,HandleBoardCast *handle)
{
if (broadcast_ != nullptr)
{
if (broadcast_->busy != 0)
{
delete handle;
return false;
}
else
{
delete broadcast_;
}
}
broadcast_=handle;
broadcast_->trun_list_to_bit(addrs);
connect(handle, &HandleBoardCast::send_data_signal, this, &prot_slave::send_data_slot);
return true;
}
void prot_slave::send_data_slot(int addr, int cmd, myarray data)
{
if ((if_ != nullptr) && (codec_ != nullptr))
{
myarray send = codec_->encode(0, addr, cmd, data);
if_->write(send);
if_->write(addr,send);
}
}
@@ -71,7 +102,7 @@ prot_slave *protSlave()
if (g_protslave == nullptr)
{
g_protslave = new prot_slave();
// g_protslave->init();
g_protslave->init();
}
return g_protslave;
}

View File

@@ -19,29 +19,43 @@ public:
addr = 0;
cmd=0;
timer_=nullptr;
timer_retry_=nullptr;
times_retry=0;
}
virtual ~HandleSlave() {
if(timer_!=nullptr){
delete timer_;
}
if(timer_retry_!=nullptr){
delete timer_retry_;
}
}
public:
virtual int start(myarray data) = 0;
virtual int dolater(int cmd, myarray data) = 0;
virtual void timeout()=0;
virtual void timeout(){timer_->stop();};
int busy;
int addr;
int cmd;
public:
int send_data(int cmd,myarray data){
emit send_data_signal(addr,cmd,data);
protected:
// 发送数据到从机
int send_data(int cmd,myarray data,int times){
this->cmd=cmd;
this->data_send=data;
this->times_retry=times;
if(timer_retry_==nullptr){
timer_retry_=new QTimer();
connect(timer_,&QTimer::timeout,this,&HandleSlave::timeout_retry);
}
timer_retry_->start(60);
return 0;
}
// 发送操作结束信号
int end(int ack,myarray data){
emit end_signal(addr,ack,data);
return 0;
}
protected:
// 开始超时计时器,此计时器用于整个操作的超时
void timeout_start(int ms){
if(timer_==nullptr){
timer_=new QTimer();
@@ -49,18 +63,158 @@ protected:
}
timer_->start(ms);
}
// 停止超时计时器,此方法同时停止重发计时器
void timeout_stop(){
if(timer_!=nullptr){
timer_->stop();
}
timeout_stop_retry();
}
// 停止数据回复超时重试计时器
void timeout_stop_retry(){
if(timer_retry_!=nullptr){
timer_retry_->stop();
}
times_retry=0;
}
private:
// 重试回调
void timeout_retry(){
if(times_retry>0){
times_retry--;
emit send_data_signal(addr,cmd,data_send);
}else{
timer_retry_->stop();
}
}
private:
QTimer *timer_;
QTimer *timer_retry_;
int times_retry;
myarray data_send;
signals:
void send_data_signal(int addr, int cmd, myarray data);
void end_signal(int addr,int ack,myarray data);
};
class HandleBoardCast : public QObject
{
Q_OBJECT
public:
HandleBoardCast() {
busy = 0;
addr = 0;
cmd=0;
timer_=nullptr;
timer_retry_=nullptr;
times_retry=0;
addr_response=0;
}
virtual ~HandleBoardCast() {
if(timer_!=nullptr){
delete timer_;
}
if(timer_retry_!=nullptr){
delete timer_retry_;
}
}
public:
virtual int start(myarray data) = 0;
virtual int dolater(int cmd, myarray data) = 0;
virtual void timeout(){timer_->stop();};
int busy;
int addr;
int addr_response;
int cmd;
public:
// 判断是否所有从机都返回
bool check_response(){
return (addr^addr_response)==0?true:false;
}
// 把地址列表转化为bit
void trun_list_to_bit(QList<int> addrs){
addr=0;
foreach(int adr,addrs){
addr|=1<<(adr-1);
}
}
protected:
// 发送数据到从机
int send_data(int cmd,myarray data,int times){
this->cmd=cmd;
this->data_send=data;
this->times_retry=times;
if(timer_retry_==nullptr){
timer_retry_=new QTimer();
connect(timer_,&QTimer::timeout,this,&HandleBoardCast::timeout_retry);
}
timer_retry_->start(300);
return 0;
}
// 发送操作结束信号
int end(int ack,myarray data){
emit end_signal(0x1f,ack,data);
return 0;
}
// 开始超时计时器,此计时器用于整个操作的超时
void timeout_start(int ms){
if(timer_==nullptr){
timer_=new QTimer();
connect(timer_,&QTimer::timeout,this,&HandleBoardCast::timeout);
}
timer_->start(ms);
}
// 停止超时计时器,此方法同时停止重发计时器
void timeout_stop(){
if(timer_!=nullptr){
timer_->stop();
}
timeout_stop_retry();
}
// 停止数据回复超时重试计时器
void timeout_stop_retry(){
if(timer_retry_!=nullptr){
timer_retry_->stop();
}
times_retry=0;
}
private:
// 重试回调
void timeout_retry(){
if(times_retry>0){
times_retry--;
myarray s;
int addr_retry=addr^addr_response;
// 这里重发只重发没有收到回应的从机
s.append(addr_retry&0xff);
s.append((addr_retry>>8)&0xff);
s.append((addr_retry>>16)&0xff);
s.append(data_send);
emit send_data_signal(0x1f,cmd,s);
}else{
timer_retry_->stop();
}
}
private:
QTimer *timer_;
QTimer *timer_retry_;
int times_retry;
myarray data_send;
signals:
void send_data_signal(int addr, int cmd, myarray data);
void end_signal(int addr,int ack,myarray data);
};
class prot_slave : public QObject
{
Q_OBJECT
@@ -69,10 +223,12 @@ public:
{
if_ = nullptr;
codec_ = nullptr;
broadcast_=nullptr;
}
~prot_slave() {}
void init();
bool set_slave_handle(int addr, HandleSlave *handle);
bool set_boardcast_handle(QList<int> addrs,HandleBoardCast *handle);
protected slots:
void send_data_slot(int addr, int cmd, myarray data);
@@ -80,6 +236,7 @@ protected:
InterFace *if_;
Codec *codec_;
QList<HandleSlave *> slaves;
HandleBoardCast *broadcast_;
};
prot_slave *protSlave();