添加广播方式升级
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -72,4 +72,5 @@ Thumbs.db
|
||||
*.exe
|
||||
|
||||
.vscode/
|
||||
quest_info.txt
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "QByteArray"
|
||||
#include "QList"
|
||||
#include "QDebug"
|
||||
|
||||
class myarray : public QByteArray
|
||||
{
|
||||
@@ -19,6 +20,7 @@ public:
|
||||
}
|
||||
myarray(int size, char data) : QByteArray(size, data) {}
|
||||
myarray(const myarray &data) : QByteArray(data) {}
|
||||
myarray(const QByteArray &data) : QByteArray(data) {}
|
||||
virtual ~myarray() {}
|
||||
char &operator[](int index)
|
||||
{
|
||||
@@ -29,6 +31,13 @@ public:
|
||||
return data()[size-1];
|
||||
return data()[index];
|
||||
}
|
||||
bool operator==(const char *s){
|
||||
return QByteArray::operator==(s);
|
||||
}
|
||||
bool operator==(const myarray &s){
|
||||
// qDebug("s1=%s,s2=%s",data(),s.data());
|
||||
return strcmp(s.data(),data())==0;
|
||||
}
|
||||
myarray &operator=(const myarray &b)
|
||||
{
|
||||
QByteArray::operator=(b);
|
||||
|
@@ -9,9 +9,10 @@
|
||||
#include "base/file.h"
|
||||
#include <QApplication>
|
||||
#include <QCryptographicHash>
|
||||
#include "complier_info.h"
|
||||
|
||||
// 配置路径
|
||||
#define CFG_PATH QString("/home/root/config/")
|
||||
#define CFG_PATH mystring("/home/root/config/")
|
||||
// #define CFG_PATH qApp->applicationDirPath()+"/config/"
|
||||
|
||||
// 配置文件
|
||||
@@ -94,6 +95,49 @@ public:
|
||||
|
||||
mycfg::mycfg()
|
||||
{
|
||||
// 加載默認參數
|
||||
tcp_enable = true;
|
||||
server_ip = mystring("192.168.10.100");
|
||||
server_port = 9527;
|
||||
local_port = 0;
|
||||
local_ip = mystring("192.168.10.50");
|
||||
gateway_ip = mystring("192.168.10.1");
|
||||
netmask = mystring("255.255.255.0");
|
||||
can_bitrate = 100000;
|
||||
local_id = 1;
|
||||
slave_num=1;
|
||||
mcu_timeout=1000;
|
||||
debug_ip=mystring("192.168.10.100");
|
||||
debug_port=5346;
|
||||
build_date=mystring(BUILD_DATE);
|
||||
cmd_port=7777;
|
||||
log_redirect=mystring("console");
|
||||
soft_version=mystring(SOFT_VERSION);
|
||||
hard_version=mystring(HARD_VERSION);
|
||||
def_lua_judge=CFG_PATH+APP_JUDGE_FILE;
|
||||
use_lua_judge=true;
|
||||
config_path=CFG_PATH;
|
||||
device_type=mystring("checker");
|
||||
moter_count=20000;
|
||||
uart_bsp=115200;
|
||||
auto_test=false;
|
||||
coder_return_mode=1;
|
||||
slave_addr_start=1;
|
||||
slave_scheme_ext=0;
|
||||
init_env();
|
||||
if(!def_shell.isEmpty())
|
||||
{
|
||||
QString str="chmod 777 %1";
|
||||
system(str.arg(def_shell).toLocal8Bit().data());
|
||||
system((def_shell).toLocal8Bit().data());
|
||||
}
|
||||
reload();
|
||||
|
||||
// 自启动时把打印路径设置为文件
|
||||
if(qApp->applicationFilePath()==AUTO_START_PATH)
|
||||
{
|
||||
log_redirect=mystring("file");
|
||||
}
|
||||
}
|
||||
|
||||
void mycfg::to_class(mystring str)
|
||||
|
@@ -30,7 +30,9 @@ SOURCES += \
|
||||
interface/codec_m4.cpp \
|
||||
interface/codec_slave.cpp \
|
||||
interface/codec_ym.cpp \
|
||||
interface/if_can.cpp \
|
||||
interface/if_tcp.cpp \
|
||||
interface/if_uart.cpp \
|
||||
interface/interface.cpp \
|
||||
main.cpp \
|
||||
mainwindow.cpp \
|
||||
@@ -52,7 +54,9 @@ HEADERS += \
|
||||
interface/codec_m4.h \
|
||||
interface/codec_slave.h \
|
||||
interface/codec_ym.h \
|
||||
interface/if_can.h \
|
||||
interface/if_tcp.h \
|
||||
interface/if_uart.h \
|
||||
interface/interface.h \
|
||||
mainwindow.h \
|
||||
prot/prot_m4.h \
|
||||
|
@@ -6,7 +6,7 @@
|
||||
|
||||
|
||||
|
||||
#define BUILD_DATE "2023-11-27 14:29:56"
|
||||
#define BUILD_DATE "2023-11-29 15:29:42"
|
||||
|
||||
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"build_date": "2023-11-27 14:29:56",
|
||||
"build_date": "2023-11-29 15:29:42",
|
||||
"hard_version": "MHPZ2_V1.00",
|
||||
"private": [
|
||||
"info.json",
|
||||
|
@@ -18,7 +18,7 @@ public:
|
||||
// virtual bool recvByte(int byte){return false;}
|
||||
// virtual myarray encode(int srcAddr, int dstAddr, int cmd, myarray data){return myarray();}
|
||||
// virtual myarray decode(int &srcAddr, int &dstAddr, int &cmd, myarray data){return myarray();}
|
||||
virtual bool packCheck(myarray data) = 0;
|
||||
virtual int packCheck(myarray data) = 0;
|
||||
virtual bool recvByte(int byte) = 0;
|
||||
virtual myarray encode(int srcAddr, int dstAddr, int cmd, myarray data) = 0;
|
||||
virtual myarray decode(int &srcAddr, int &dstAddr, int &cmd, myarray data) = 0;
|
||||
|
@@ -43,17 +43,17 @@ bool codec_m4::recvByte(int byte)
|
||||
return fullFrame;
|
||||
}
|
||||
|
||||
bool codec_m4::packCheck(myarray data)
|
||||
int codec_m4::packCheck(myarray data)
|
||||
{
|
||||
if (data[0] != 0xff)
|
||||
{
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
if (data.size() >= 2 && (data.size() == (data[1] + 2)))
|
||||
if (data.size() >= 2 && (data.size() >= (data[1] + 2)))
|
||||
{
|
||||
return true;
|
||||
return data[1] + 2;
|
||||
}
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
myarray codec_m4::encode(int srcAddr, int dstAddr, int cmd, myarray data)
|
||||
@@ -66,6 +66,7 @@ myarray codec_m4::encode(int srcAddr, int dstAddr, int cmd, myarray data)
|
||||
}
|
||||
myarray codec_m4::decode(int &srcAddr, int &dstAddr, int &cmd, myarray data)
|
||||
{
|
||||
// qDebug("m4 recv:%s",data.toHex(' ').data());
|
||||
if (packCheck(data))
|
||||
{
|
||||
return data.mid(2);
|
||||
|
@@ -6,7 +6,7 @@ class codec_m4 : public Codec
|
||||
{
|
||||
public:
|
||||
codec_m4() { num_to_read = 0; }
|
||||
virtual bool packCheck(myarray data);
|
||||
virtual int packCheck(myarray data);
|
||||
virtual bool recvByte(int byte);
|
||||
virtual myarray encode(int srcAddr, int dstAddr, int cmd, myarray data);
|
||||
virtual myarray decode(int &srcAddr, int &dstAddr, int &cmd, myarray data);
|
||||
|
@@ -26,6 +26,14 @@ myarray codec_slave::decode(int &srcAddr, int &dstAddr, int &cmd, myarray data)
|
||||
{
|
||||
myarray r;
|
||||
QString str_err = "ok";
|
||||
|
||||
if(data.size()==1){
|
||||
srcAddr = data[0];
|
||||
dstAddr = 0;
|
||||
r.append(char(0));
|
||||
return r;
|
||||
}
|
||||
|
||||
if (data.size() < 10)
|
||||
{
|
||||
// 一帧数据至少10字节
|
||||
|
@@ -9,7 +9,7 @@ public:
|
||||
codec_slave() : Codec()
|
||||
{
|
||||
}
|
||||
virtual bool packCheck(myarray data) { return false; }
|
||||
virtual int packCheck(myarray data) { return data.size(); }
|
||||
virtual bool recvByte(int byte) { return false; }
|
||||
virtual myarray encode(int srcAddr, int dstAddr, int cmd, myarray data);
|
||||
virtual myarray decode(int &srcAddr, int &dstAddr, int &cmd, myarray data);
|
||||
|
@@ -75,15 +75,28 @@ myarray CodecYm::decode(int &srcAddr, int &dstAddr, int &cmd, myarray data)
|
||||
{
|
||||
cmd = this->cmd;
|
||||
if (is_big_data == false)
|
||||
r = data.mid(7, len - 3);
|
||||
r = data.mid(offset+7, len - 3);
|
||||
else
|
||||
r = data.mid(11, len - 7);
|
||||
r = data.mid(offset+11, len - 7);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
bool CodecYm::packCheck(myarray data)
|
||||
int CodecYm::packCheck(myarray data)
|
||||
{
|
||||
bool ack = false;
|
||||
int ack = 0;
|
||||
offset=0;
|
||||
while(data.size()>=2){
|
||||
if ((uint8_t(data[0]) != 0x59u) || (uint8_t(data[1]) != 0x6du))
|
||||
{
|
||||
// 帧头不对
|
||||
// qWarning("frame head not 0x59 0x6d");
|
||||
// return ack;
|
||||
data.remove(0,1);
|
||||
offset++;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (data.size() < 9)
|
||||
{
|
||||
// 主机一帧数据至少9字节
|
||||
@@ -91,13 +104,6 @@ bool CodecYm::packCheck(myarray data)
|
||||
return ack;
|
||||
}
|
||||
|
||||
if ((uint8_t(data[0]) != 0x59u) || (uint8_t(data[1]) != 0x6du))
|
||||
{
|
||||
// 帧头不对
|
||||
qWarning("frame head not 0x59 0x6d");
|
||||
return ack;
|
||||
}
|
||||
|
||||
len = (data[2] | (data[3] << 8));
|
||||
if (len == 65535)
|
||||
{
|
||||
@@ -109,7 +115,7 @@ bool CodecYm::packCheck(myarray data)
|
||||
{
|
||||
is_big_data = false;
|
||||
}
|
||||
if (len + 6 != data.size())
|
||||
if (len + 6 > data.size())
|
||||
{
|
||||
// 如果长度不相等则产生了数据丢失
|
||||
qWarning("recv data have lossed");
|
||||
@@ -127,7 +133,7 @@ bool CodecYm::packCheck(myarray data)
|
||||
cmd_no = data[5] | (data[6] << 8);
|
||||
cmd = data[4];
|
||||
// 数据负载
|
||||
return true;
|
||||
return len+offset;
|
||||
}
|
||||
myarray CodecYm::encode(int srcAddr, int dstAddr, int cmd, myarray data)
|
||||
{
|
||||
|
@@ -11,13 +11,14 @@ public:
|
||||
{
|
||||
is_big_data = false;
|
||||
num_to_read = 0;
|
||||
offset=0;
|
||||
}
|
||||
~CodecYm() {}
|
||||
// 重载接收字节函数
|
||||
bool recvByte(int byte);
|
||||
// 重载解码函数
|
||||
myarray decode(int &srcAddr, int &dstAddr, int &cmd, myarray data);
|
||||
bool packCheck(myarray data);
|
||||
int packCheck(myarray data);
|
||||
myarray encode(int srcAddr, int dstAddr, int cmd, myarray data);
|
||||
|
||||
private:
|
||||
@@ -26,6 +27,7 @@ private:
|
||||
int cmd_no;
|
||||
int cmd;
|
||||
int len;
|
||||
int offset;
|
||||
};
|
||||
|
||||
#endif // CODEC_YM_H
|
||||
|
334
interface/if_can.cpp
Normal file
334
interface/if_can.cpp
Normal file
@@ -0,0 +1,334 @@
|
||||
|
||||
|
||||
#include "interface/if_can.h"
|
||||
#include <QDebug>
|
||||
#include "QTimer"
|
||||
#include "base/crc.h"
|
||||
#include <QtEndian>
|
||||
#include "QThread"
|
||||
#include "base/mycfg.h"
|
||||
|
||||
#define QT_NO_DEBUG_OUTPUT
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Reserve1 : 3;
|
||||
uint32_t srcMACID : 5;
|
||||
uint32_t Reserve0 : 2;
|
||||
uint32_t destMACID : 5;
|
||||
uint32_t ACK : 1;
|
||||
uint32_t FunClass : 6;
|
||||
uint32_t SegFlag : 2;
|
||||
uint32_t SegNum : 8;
|
||||
} YeCanID_st;
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint32_t Exide;
|
||||
YeCanID_st yecanid;
|
||||
} YeCanID_un;
|
||||
|
||||
can_slave::can_slave()
|
||||
{
|
||||
addr = 0;
|
||||
recv_pack_num = 0;
|
||||
}
|
||||
|
||||
// 定义带参的沟道函数,供QList调用
|
||||
can_slave::can_slave(const can_slave &b) : QObject()
|
||||
{
|
||||
this->addr = b.addr;
|
||||
this->recv_data = b.recv_data;
|
||||
this->recv_pack_num = b.recv_pack_num;
|
||||
}
|
||||
|
||||
can_slave::~can_slave()
|
||||
{
|
||||
}
|
||||
|
||||
can_slave &can_slave::operator=(const can_slave &b)
|
||||
{
|
||||
this->addr = b.addr;
|
||||
this->recv_data = b.recv_data;
|
||||
this->recv_pack_num = b.recv_pack_num;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void can_slave::append(QByteArray data)
|
||||
{
|
||||
recv_data.append(data);
|
||||
recv_pack_num++;
|
||||
}
|
||||
|
||||
QByteArray can_slave::get_data()
|
||||
{
|
||||
return recv_data;
|
||||
}
|
||||
int can_slave::get_pack_num()
|
||||
{
|
||||
return recv_pack_num;
|
||||
}
|
||||
|
||||
void can_slave::clear()
|
||||
{
|
||||
recv_data.clear();
|
||||
recv_pack_num = 0;
|
||||
}
|
||||
|
||||
can_host::can_host(int bitrate)
|
||||
{
|
||||
this->bitrate = bitrate;
|
||||
this->can_ = nullptr;
|
||||
timer_ = nullptr;
|
||||
}
|
||||
|
||||
can_host::~can_host()
|
||||
{
|
||||
}
|
||||
|
||||
// 用于返回指定地址的从机对象
|
||||
can_slave &can_host::get_slave_by_addr(uint8_t addr)
|
||||
{
|
||||
for (int i = 0; i < slaves.size(); i++)
|
||||
{
|
||||
if (slaves[i].addr == addr)
|
||||
return slaves[i];
|
||||
}
|
||||
|
||||
// 如果没有对应地址的从机,则添加一个
|
||||
can_slave c;
|
||||
c.addr = addr;
|
||||
slaves.append(c);
|
||||
return slaves[slaves.size() - 1];
|
||||
}
|
||||
|
||||
void can_host::init()
|
||||
{
|
||||
QTimer::singleShot(0, this, &can_host::init_cb);
|
||||
}
|
||||
|
||||
void can_host::init_cb()
|
||||
{
|
||||
|
||||
if (nullptr == can_)
|
||||
{
|
||||
/* 先关闭can0 */
|
||||
system("ifconfig can0 down");
|
||||
QString cmd = tr("ip link set up can0 type can bitrate %1 restart-ms 100").arg(bitrate);
|
||||
/* 使用系统指令以设置的比特率初始化CAN */
|
||||
// qDebug()<< "can cmd:"<<cmd<<endl;
|
||||
system(cmd.toStdString().c_str());
|
||||
system("echo 4096 > /sys/class/net/can0/tx_queue_len");
|
||||
|
||||
QString errorString;
|
||||
can_ = QCanBus::instance()->createDevice("socketcan", "can0", &errorString);
|
||||
if (!can_)
|
||||
{
|
||||
qWarning() << "Error creating device can0,reson:" << errorString;
|
||||
return;
|
||||
}
|
||||
/* 连接CAN */
|
||||
if (!can_->connectDevice())
|
||||
{
|
||||
qWarning() << "device can0 Connection error:" << can_->errorString();
|
||||
delete can_;
|
||||
can_ = nullptr;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 连接收到数据信号和错误信号
|
||||
connect(can_, SIGNAL(framesReceived()), this, SLOT(recv_data_cb()));
|
||||
}
|
||||
}
|
||||
|
||||
// 发送完成回调
|
||||
void can_host::freams_sent_cb(qint64 count)
|
||||
{
|
||||
Q_UNUSED(count);
|
||||
qDebug() << "freams sent.count=" << count;
|
||||
if (!send_packets.isEmpty())
|
||||
{
|
||||
QCanBusFrame f = send_packets.at(0);
|
||||
if (can_->writeFrame(f) == true)
|
||||
send_packets.removeAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 收到can数据的回调
|
||||
void can_host::recv_data_cb()
|
||||
{
|
||||
YeCanID_un frame_id;
|
||||
while (can_->framesAvailable())
|
||||
{
|
||||
const QCanBusFrame frame = can_->readFrame();
|
||||
frame_id.Exide = frame.frameId();
|
||||
if (frame_id.Exide == 0x000000)
|
||||
return;
|
||||
QByteArray payload = frame.payload();
|
||||
uint8_t slave_addr = frame_id.yecanid.srcMACID;
|
||||
uint8_t dst_addr = frame_id.yecanid.destMACID;
|
||||
uint8_t seg_flag = frame_id.yecanid.SegFlag;
|
||||
int seg_num = frame_id.yecanid.SegNum;
|
||||
can_slave &slave = get_slave_by_addr(slave_addr);
|
||||
if (seg_flag == 0x00)
|
||||
{
|
||||
// 不分段
|
||||
slave.clear();
|
||||
slave.append(payload);
|
||||
if (dst_addr == 0){
|
||||
if (irq_fun)
|
||||
{
|
||||
irq_fun(myarray(slave.get_data()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (seg_flag == 0x01)
|
||||
{
|
||||
// 首段
|
||||
slave.clear();
|
||||
slave.append(payload);
|
||||
}
|
||||
else if (seg_flag == 0x02)
|
||||
{
|
||||
// 中段
|
||||
slave.append(payload);
|
||||
}
|
||||
else if (seg_flag == 0x03)
|
||||
{
|
||||
// 尾段
|
||||
slave.append(payload);
|
||||
if (slave.get_pack_num() - 1 == seg_num)
|
||||
{
|
||||
if (dst_addr == 0){
|
||||
if (irq_fun)
|
||||
{
|
||||
irq_fun(myarray(slave.get_data()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "can data from: " << QString::number(slave_addr, 10) << "recv error";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int can_host::write(int dst,myarray data)
|
||||
{
|
||||
append(dst, 1, data);
|
||||
return data.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void can_host::send_data_cb(uint8_t dst, int fun_class, QByteArray data)
|
||||
{
|
||||
append(dst, fun_class, data);
|
||||
}
|
||||
|
||||
// 群发消息
|
||||
void can_host::send_data_mul_cb(QList<uint8_t> dst, int fun_class, QByteArray data)
|
||||
{
|
||||
for (int i = 0; i < dst.size(); i++)
|
||||
append(dst[i], fun_class, data);
|
||||
}
|
||||
|
||||
void can_host::append(uint8_t addr, uint8_t fun_class, QByteArray data)
|
||||
{
|
||||
YeCanID_un frameId;
|
||||
frameId.Exide = 0;
|
||||
frameId.yecanid.destMACID = addr;
|
||||
frameId.yecanid.srcMACID = 0;
|
||||
frameId.yecanid.FunClass = fun_class;
|
||||
frameId.yecanid.SegFlag = 0;
|
||||
frameId.yecanid.SegNum = 0;
|
||||
|
||||
// 单包发送
|
||||
if (data.size() <= 8)
|
||||
{
|
||||
frameId.yecanid.SegFlag = 0x0;
|
||||
frameId.yecanid.SegNum = 0;
|
||||
QCanBusFrame frame = QCanBusFrame(frameId.Exide, data.left(8));
|
||||
while (can_->writeFrame(frame) != true)
|
||||
{
|
||||
can_->waitForFramesWritten(1000);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 按8字节分包发送
|
||||
for (int i = 0; !data.isEmpty(); i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
frameId.yecanid.SegFlag = 0x1;
|
||||
}
|
||||
else if (data.size() > 8)
|
||||
{
|
||||
frameId.yecanid.SegFlag = 0x2;
|
||||
}
|
||||
else
|
||||
{
|
||||
frameId.yecanid.SegFlag = 0x3;
|
||||
}
|
||||
frameId.yecanid.SegNum = (uint8_t)i;
|
||||
QCanBusFrame frame = QCanBusFrame(frameId.Exide, data.left(8));
|
||||
while (can_->writeFrame(frame) != true)
|
||||
{
|
||||
can_->waitForFramesWritten(1000);
|
||||
}
|
||||
data.remove(0, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void can_host::on_error_cb(QCanBusDevice::CanBusError err)
|
||||
{
|
||||
switch (err)
|
||||
{
|
||||
case QCanBusDevice::ReadError:
|
||||
qWarning() << "ReadError" << can_->errorString();
|
||||
break;
|
||||
case QCanBusDevice::WriteError:
|
||||
qWarning() << "WriteError" << can_->errorString();
|
||||
break;
|
||||
case QCanBusDevice::ConnectionError:
|
||||
qWarning() << "ConnectionError" << can_->errorString();
|
||||
break;
|
||||
case QCanBusDevice::ConfigurationError:
|
||||
qWarning() << "ConfigurationError" << can_->errorString();
|
||||
break;
|
||||
case QCanBusDevice::UnknownError:
|
||||
qWarning() << "UnknowError" << can_->errorString();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
InterFace *if_can_get()
|
||||
{
|
||||
static InterFace *if_ = nullptr;
|
||||
if (if_ == nullptr)
|
||||
{
|
||||
int bsp=200000;
|
||||
if(syscfg()->can_bitrate!=0){
|
||||
bsp=syscfg()->can_bitrate;
|
||||
}
|
||||
if_ = new can_host(bsp);
|
||||
QTimer::singleShot(0, if_, &InterFace::init);
|
||||
}
|
||||
return if_;
|
||||
}
|
||||
|
||||
if_export(can, if_can_get);
|
||||
|
||||
|
75
interface/if_can.h
Normal file
75
interface/if_can.h
Normal file
@@ -0,0 +1,75 @@
|
||||
#ifndef if_can_h__
|
||||
#define if_can_h__
|
||||
|
||||
#include <base/base.h>
|
||||
#include <QObject>
|
||||
#include <QCanBus>
|
||||
#include <QCanBusDevice>
|
||||
#include "stdint-gcc.h"
|
||||
#include "QList"
|
||||
#include "QTimer"
|
||||
#include "interface/interface.h"
|
||||
|
||||
// 定义can从机对象
|
||||
class can_slave : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
uint8_t addr;
|
||||
can_slave();
|
||||
can_slave(const can_slave &b);
|
||||
~can_slave();
|
||||
can_slave &operator=(const can_slave &b);
|
||||
void append(QByteArray data);
|
||||
QByteArray get_data();
|
||||
int get_pack_num();
|
||||
void clear();
|
||||
bool is_empty()
|
||||
{
|
||||
if (recv_data.size() == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
QByteArray recv_data;
|
||||
int recv_pack_num;
|
||||
};
|
||||
|
||||
// 定义can主机对象
|
||||
class can_host : public InterFace
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
can_host(int bitrate);
|
||||
~can_host();
|
||||
// 用户调用这个函数初始化
|
||||
void init();
|
||||
int write(myarray data){return 0;}
|
||||
int write(int dst,myarray data);
|
||||
|
||||
private:
|
||||
can_slave &get_slave_by_addr(uint8_t addr);
|
||||
void append(uint8_t addr, uint8_t fun_class, QByteArray data);
|
||||
public slots:
|
||||
// 用户把发送数据信号连接到这个槽
|
||||
void send_data_cb(uint8_t dst, int fun_class, QByteArray data);
|
||||
void send_data_mul_cb(QList<uint8_t> dst, int fun_class, QByteArray data);
|
||||
|
||||
private slots:
|
||||
void freams_sent_cb(qint64 count);
|
||||
void recv_data_cb();
|
||||
void on_error_cb(QCanBusDevice::CanBusError err);
|
||||
void init_cb();
|
||||
// void timerout_cb();
|
||||
private:
|
||||
int bitrate;
|
||||
QCanBusDevice *can_;
|
||||
QList<can_slave> slaves;
|
||||
QList<QCanBusFrame> send_packets;
|
||||
QList<QCanBusFrame> recv_packets;
|
||||
QTimer *timer_;
|
||||
};
|
||||
|
||||
#endif
|
109
interface/if_uart.cpp
Normal file
109
interface/if_uart.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
|
||||
#include "if_uart.h"
|
||||
#include "QThread"
|
||||
#include "base/mycfg.h"
|
||||
#include "QDebug"
|
||||
|
||||
|
||||
void if_uart::init()
|
||||
{
|
||||
if(serial_==nullptr)
|
||||
{
|
||||
serial_=new QSerialPort();
|
||||
serial_->setPortName(com);
|
||||
serial_->setBaudRate(bsp);
|
||||
serial_->setParity(QSerialPort::NoParity);
|
||||
serial_->setDataBits(QSerialPort::Data8);
|
||||
serial_->setStopBits(QSerialPort::OneStop);
|
||||
serial_->setFlowControl(QSerialPort::NoFlowControl);
|
||||
if(serial_->open(QIODevice::ReadWrite))
|
||||
{
|
||||
connect(serial_,&QSerialPort::readyRead,this,&if_uart::ready_read_cb);
|
||||
qDebug("uart \"%s\" bsp=%d",serial_->portName().toLocal8Bit().data(), bsp);
|
||||
serial_open=true;
|
||||
} else
|
||||
{
|
||||
qWarning()<<"uart open failed."<<serial_->portName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int if_uart::write(myarray data)
|
||||
{
|
||||
if((nullptr == serial_)||(serial_open!=true))
|
||||
{
|
||||
//qWarning() << "Can’t send data , TcpClient socket not connect.";
|
||||
return 0;
|
||||
}
|
||||
qDebug("uart send:%s",data.toHex(' ').data());
|
||||
|
||||
int wb = serial_->write(data);
|
||||
if((!serial_->flush())||(wb!=data.size()))
|
||||
{
|
||||
//qWarning() << "uart data:"<<data.toHex(' ')<<"not sent.";
|
||||
}
|
||||
return wb;
|
||||
}
|
||||
|
||||
void if_uart::ready_read_cb()
|
||||
{
|
||||
QByteArray data = serial_->readAll();
|
||||
qDebug("uart recv:%s",data.toHex(' ').data());
|
||||
if (irq_fun)
|
||||
{
|
||||
irq_fun(myarray(data));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
InterFace *if_uart_hmi()
|
||||
{
|
||||
static InterFace *if_ = nullptr;
|
||||
if (if_ == nullptr)
|
||||
{
|
||||
if_ = new if_uart("/dev/ttySTM1",115200);
|
||||
// QTimer::singleShot(0, if_, &InterFace::init);
|
||||
if_->init();
|
||||
}
|
||||
return if_;
|
||||
}
|
||||
|
||||
if_export(uart_hmi, if_uart_hmi);
|
||||
|
||||
|
||||
|
||||
InterFace *if_uart_host()
|
||||
{
|
||||
static InterFace *if_ = nullptr;
|
||||
if (if_ == nullptr)
|
||||
{
|
||||
int bsp=57600;
|
||||
if(syscfg()->uart_bsp!=0){
|
||||
bsp=syscfg()->uart_bsp;
|
||||
}
|
||||
if_ = new if_uart("/dev/ttySTM2",bsp);
|
||||
// QTimer::singleShot(0, if_, &InterFace::init);
|
||||
if_->init();
|
||||
}
|
||||
return if_;
|
||||
}
|
||||
|
||||
if_export(uart_host, if_uart_host);
|
||||
|
||||
|
||||
|
||||
InterFace *if_uart_m4()
|
||||
{
|
||||
static InterFace *if_ = nullptr;
|
||||
if (if_ == nullptr)
|
||||
{
|
||||
if_ = new if_uart("/dev/ttyRPMSG0",115200);
|
||||
// QTimer::singleShot(0, if_, &InterFace::init);
|
||||
if_->init();
|
||||
}
|
||||
return if_;
|
||||
}
|
||||
|
||||
if_export(uart_m4, if_uart_m4);
|
||||
|
51
interface/if_uart.h
Normal file
51
interface/if_uart.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef if_uart_h__
|
||||
#define if_uart_h__
|
||||
|
||||
|
||||
#include <QObject>
|
||||
#include <interface/interface.h>
|
||||
#include "QTimer"
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include "QByteArray"
|
||||
#include "base/mycfg.h"
|
||||
#include <QSerialPort> // 提供访问串口的功能
|
||||
#include <QSerialPortInfo> // 提供系统中存在的串口信息
|
||||
|
||||
|
||||
|
||||
|
||||
class if_uart : public InterFace
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
if_uart(mystring com,int bsp):InterFace(){
|
||||
this->com = com;
|
||||
this->bsp = bsp;
|
||||
serial_=nullptr;
|
||||
serial_open=false;
|
||||
}
|
||||
virtual ~if_uart(){
|
||||
if(serial_open==true){
|
||||
serial_->close();
|
||||
delete serial_;
|
||||
}
|
||||
};
|
||||
void init();
|
||||
int write(myarray data);
|
||||
protected slots:
|
||||
void ready_read_cb();
|
||||
protected:
|
||||
mystring com;
|
||||
int bsp;
|
||||
QSerialPort *serial_;
|
||||
bool serial_open;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
@@ -16,6 +16,7 @@ InterFace *interFaceFind(const char *name)
|
||||
{
|
||||
if (strcmp(name, item->name) == 0)
|
||||
return item->if_get_fun();
|
||||
// qDebug("if dev: %s",item->name);
|
||||
}
|
||||
}
|
||||
qWarning("can not find interface named '%s'", name);
|
||||
|
@@ -22,6 +22,9 @@ public:
|
||||
{
|
||||
this->irq_fun = fun;
|
||||
}
|
||||
virtual int write(int dst,myarray data){
|
||||
return write(data);
|
||||
}
|
||||
|
||||
protected:
|
||||
irq_cb irq_fun;
|
||||
|
59
main.cpp
59
main.cpp
@@ -6,55 +6,38 @@
|
||||
#include <QTextCodec>
|
||||
#include "base/base.h"
|
||||
#include "base/mycfg.h"
|
||||
#include "base/check_cfg.h"
|
||||
#include "interface/interface.h"
|
||||
#include "prot/prot_m4.h"
|
||||
#include "prot/prot_pc.h"
|
||||
#include "prot/prot_slave.h"
|
||||
|
||||
#define log(fmt, ...) \
|
||||
{ \
|
||||
QString str = QString::asprintf(fmt, ##__VA_ARGS__); \
|
||||
printf("%s", str.toLocal8Bit().data()); \
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
using namespace std::placeholders;
|
||||
|
||||
typedef std::function<void(int, int)> Fun;
|
||||
|
||||
class B
|
||||
{
|
||||
public:
|
||||
void call(int a, Fun f)
|
||||
{
|
||||
f(a, 2);
|
||||
}
|
||||
};
|
||||
|
||||
class Test
|
||||
{
|
||||
public:
|
||||
void callback(int a, int b)
|
||||
{
|
||||
// qDebug()<<a<<"+"<<b<<"="<<a+b<<endl;
|
||||
qDebug("%d+%d=%d,%s", a, b, a + b, QString("ssssss").toLocal8Bit().data());
|
||||
}
|
||||
|
||||
void bind()
|
||||
{
|
||||
Fun fun = std::bind(&Test::callback, this, _1, _2);
|
||||
B b;
|
||||
b.call(1, fun);
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
// Test test;
|
||||
// test.bind();
|
||||
|
||||
qDebug("local ip=%s", syscfg()->local_ip.data());
|
||||
InterFace *if_ = interFaceFind("tcp");
|
||||
// w.show();
|
||||
syscfg();
|
||||
check_plan();
|
||||
prot_m4 *m4=protM4();
|
||||
protPc();
|
||||
protSlave();
|
||||
|
||||
// 获取m4的编译时间
|
||||
m4->set_irq_fun([=](myarray data){
|
||||
qDebug("m4 app:%s",data.data());
|
||||
m4->del_irq_fun(nullptr,"buildtime: ");
|
||||
},"buildtime: ");
|
||||
m4->send_data_slot("build");
|
||||
m4->set_irq_fun([=](myarray data){
|
||||
qDebug("m4 app: moter inited");
|
||||
m4->del_irq_fun(nullptr,"moterinited");
|
||||
},"moterinited");
|
||||
m4->send_data_slot("moterinit");
|
||||
return app.exec();
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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();
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -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_, \
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -30,8 +30,8 @@ myarray moter_ctrl(myarray op)
|
||||
moter->moter_run = 1;
|
||||
count = -moter->moter_count - 100;
|
||||
moter->moter_count = 0;
|
||||
QString s = QString("moter %1").arg(count);
|
||||
r = s.toLocal8Bit();
|
||||
mystring s = mystring("moter %1").arg(count);
|
||||
r = myarray(s.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -47,8 +47,9 @@ myarray moter_ctrl(myarray op)
|
||||
moter->moter_run = 1;
|
||||
count = cfg_->moter_count - moter->moter_count;
|
||||
moter->moter_count += count;
|
||||
QString s = QString("moter %1").arg(count);
|
||||
r = s.toLocal8Bit();
|
||||
mystring s = mystring("moter %1").arg(count);
|
||||
r = myarray(s.data());
|
||||
qDebug("moter down:%s",s.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -56,7 +57,8 @@ myarray moter_ctrl(myarray op)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
qDebug("moter ctrl:%s",op.data());
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,23 +70,24 @@ int selfdev_check::dolater(int cmd, myarray data)
|
||||
mycfg *cfg=syscfg();
|
||||
busy=1;
|
||||
connect(this, &selfdev_check::send_to_m4_signal, m4, &prot_m4::send_data_slot);
|
||||
m4->set_irq_fun([=](myarray data)
|
||||
{
|
||||
m4->del_irq_fun(nullptr,"moter ");
|
||||
if(data=="down"){
|
||||
// 这里开始检测
|
||||
QList<int> addrs=cfg->calc_slave_addrs();
|
||||
HandleSlave *s=new slave_check();
|
||||
foreach(int addr, addrs){
|
||||
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);
|
||||
}
|
||||
prot_m4_cb moter_down_cb=[=](myarray data)
|
||||
{
|
||||
m4->del_irq_fun(moter_down_cb,"moter ");
|
||||
if(data=="down"){
|
||||
// 这里开始检测
|
||||
QList<int> addrs=cfg->calc_slave_addrs();
|
||||
HandleSlave *s=new slave_check();
|
||||
foreach(int addr, addrs){
|
||||
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);
|
||||
}
|
||||
}
|
||||
},"moter ");
|
||||
}
|
||||
};
|
||||
m4->set_irq_fun(moter_down_cb,"moter ");
|
||||
emit send_to_m4_signal(moter_ctrl("down"));
|
||||
slave_acked.clear();
|
||||
for(int i=0;i<cfg->slave_num;i++){
|
||||
@@ -148,8 +151,32 @@ void selfdev_check::slave_end_slot(int addr,int ack, myarray data)
|
||||
static HandlePc *get_selfdev_check(){
|
||||
return new selfdev_check();
|
||||
}
|
||||
protpc_export(0x30, get_selfdev_check);
|
||||
|
||||
protpc_export(0xff, get_selfdev_check);
|
||||
int selfdev_moter::dolater(int cmd, myarray data)
|
||||
{
|
||||
prot_m4 *m4 = protM4();
|
||||
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"));
|
||||
}
|
||||
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);
|
||||
|
||||
|
||||
|
||||
|
@@ -22,4 +22,22 @@ signals:
|
||||
void send_to_m4_signal(myarray data);
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 电机 自研批检仪
|
||||
class selfdev_moter : public HandlePc
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
selfdev_moter() : HandlePc() {}
|
||||
~selfdev_moter() {}
|
||||
int dolater(int cmd, myarray data);
|
||||
void timeout();
|
||||
signals:
|
||||
void send_to_m4_signal(myarray data);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -2,23 +2,26 @@
|
||||
#include "base/mycfg.h"
|
||||
#include "base/check_cfg.h"
|
||||
#include "QDebug"
|
||||
#include "base/crc.h"
|
||||
|
||||
|
||||
|
||||
int slave_check::start(myarray data)
|
||||
{
|
||||
mycfg *cfg_=syscfg();
|
||||
int timeout=100000;
|
||||
check_cfg *ccfg_=check_plan();
|
||||
int timeout=ccfg_->get_check_time_out();
|
||||
busy=1;
|
||||
cmd=0x0c;
|
||||
qDebug("addr %d start check,timeout=%d",addr,timeout);
|
||||
send_data(cmd,myarray());
|
||||
send_data(cmd,myarray(),3);
|
||||
timeout_start(timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void slave_check::timeout()
|
||||
{
|
||||
timeout_stop();
|
||||
qWarning("addr %d check timeout.",addr);
|
||||
end(1,myarray());
|
||||
busy=0;
|
||||
@@ -30,11 +33,255 @@ int slave_check::dolater(int cmd, myarray data)
|
||||
qWarning("addr %d recv err cmd:%02x",addr,cmd);
|
||||
return 1;
|
||||
}
|
||||
end(0,data);
|
||||
busy=0;
|
||||
timeout_stop_retry();
|
||||
if(data.size()<=16){
|
||||
qDebug("addr %d recv first ack.",addr);
|
||||
}else{
|
||||
qDebug("addr %d recv secend ack.",addr);
|
||||
send_data(0x14,myarray(),1);
|
||||
end(0,data);
|
||||
busy=0;
|
||||
timeout_stop();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void slave_result::timeout()
|
||||
{
|
||||
timeout_stop();
|
||||
qWarning("addr %d result timeout.",addr);
|
||||
end(1,myarray());
|
||||
busy=0;
|
||||
}
|
||||
|
||||
int slave_result::start(myarray data)
|
||||
{
|
||||
int timeout=2000;
|
||||
busy=1;
|
||||
cmd=0x02;
|
||||
qDebug("addr %d read result,timeout=%d",addr,timeout);
|
||||
send_data(cmd,myarray(),10);
|
||||
timeout_start(timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int slave_result::dolater(int cmd, myarray data)
|
||||
{
|
||||
if(cmd!=this->cmd){
|
||||
qWarning("addr %d recv err cmd:%02x",addr,cmd);
|
||||
return 1;
|
||||
}
|
||||
timeout_stop_retry();
|
||||
end(0,data);
|
||||
busy=0;
|
||||
timeout_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void slave_sethardver::timeout()
|
||||
{
|
||||
timeout_stop();
|
||||
qWarning("addr %d sethardver timeout.",addr);
|
||||
end(1,myarray());
|
||||
busy=0;
|
||||
}
|
||||
|
||||
int slave_sethardver::start(myarray data)
|
||||
{
|
||||
int timeout=2000;
|
||||
busy=1;
|
||||
cmd=0x03;
|
||||
qDebug("addr %d read sethardver,timeout=%d",addr,timeout);
|
||||
send_data(cmd,data,10);
|
||||
timeout_start(timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int slave_sethardver::dolater(int cmd, myarray data)
|
||||
{
|
||||
if(cmd!=this->cmd){
|
||||
qWarning("addr %d recv err cmd:%02x",addr,cmd);
|
||||
return 1;
|
||||
}
|
||||
timeout_stop_retry();
|
||||
end(0,data);
|
||||
busy=0;
|
||||
timeout_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void slave_setresver::timeout()
|
||||
{
|
||||
timeout_stop();
|
||||
qWarning("addr %d setresver timeout.",addr);
|
||||
end(1,myarray());
|
||||
busy=0;
|
||||
}
|
||||
|
||||
int slave_setresver::start(myarray data)
|
||||
{
|
||||
int timeout=2000;
|
||||
busy=1;
|
||||
cmd=0x04;
|
||||
qDebug("addr %d read setresver,timeout=%d",addr,timeout);
|
||||
send_data(cmd,data,10);
|
||||
timeout_start(timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int slave_setresver::dolater(int cmd, myarray data)
|
||||
{
|
||||
if(cmd!=this->cmd){
|
||||
qWarning("addr %d recv err cmd:%02x",addr,cmd);
|
||||
return 1;
|
||||
}
|
||||
timeout_stop_retry();
|
||||
end(0,data);
|
||||
busy=0;
|
||||
timeout_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void slave_resvalue::timeout()
|
||||
{
|
||||
timeout_stop();
|
||||
qWarning("addr %d resvalue timeout.",addr);
|
||||
end(1,myarray());
|
||||
busy=0;
|
||||
}
|
||||
|
||||
int slave_resvalue::start(myarray data)
|
||||
{
|
||||
int timeout=2000;
|
||||
busy=1;
|
||||
cmd=0x05;
|
||||
qDebug("addr %d read resvalue,timeout=%d",addr,timeout);
|
||||
send_data(cmd,data,10);
|
||||
timeout_start(timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int slave_resvalue::dolater(int cmd, myarray data)
|
||||
{
|
||||
if(cmd!=this->cmd){
|
||||
qWarning("addr %d recv err cmd:%02x",addr,cmd);
|
||||
return 1;
|
||||
}
|
||||
timeout_stop_retry();
|
||||
end(0,data);
|
||||
busy=0;
|
||||
timeout_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 定义地址宏
|
||||
// 本程序中程序下载地址不是这个地址,在此用来计算偏移量
|
||||
#define MCU_APP_ADDR_BASE 0x8004000
|
||||
#define MCU_TASKID_ADDR_BASE 0x803f000
|
||||
#define MCU_JWT_ADDR_BASE 0x803B000
|
||||
|
||||
|
||||
|
||||
void boardcast_updata::timeout()
|
||||
{
|
||||
timeout_stop();
|
||||
qWarning("addr %d updata timeout.",addr);
|
||||
end(1,myarray());
|
||||
busy=0;
|
||||
}
|
||||
|
||||
int boardcast_updata::start(myarray data)
|
||||
{
|
||||
int timeout=5000;
|
||||
busy=1;
|
||||
qWarning()<<"addr "<<addr<<" updata start.";
|
||||
timeout_start(timeout);
|
||||
// 擦除
|
||||
step=0;
|
||||
send_data(0xfe,data,10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int boardcast_updata::dolater(int cmd, myarray data)
|
||||
{
|
||||
timeout_stop_retry();
|
||||
timeout_start(5000);
|
||||
if(step==0){
|
||||
if(send_packet()==true){
|
||||
step=1;
|
||||
}
|
||||
}else if(step==1){
|
||||
uint32_t addr_start=MCU_APP_ADDR_BASE;
|
||||
uint32_t addr_end=MCU_APP_ADDR_BASE+count_sent;
|
||||
uint32_t crc32=crc::crc32(this->data);
|
||||
myarray s;
|
||||
s.append((addr_start)&0xff);
|
||||
s.append((addr_start>>8)&0xff);
|
||||
s.append((addr_start>>16)&0xff);
|
||||
s.append((addr_start>>24)&0xff);
|
||||
s.append((addr_end)&0xff);
|
||||
s.append((addr_end>>8)&0xff);
|
||||
s.append((addr_end>>16)&0xff);
|
||||
s.append((addr_end>>24)&0xff);
|
||||
s.append((crc32)&0xff);
|
||||
s.append((crc32>>8)&0xff);
|
||||
s.append((crc32>>16)&0xff);
|
||||
s.append((crc32>>24)&0xff);
|
||||
send_data(0xfb,s,10);
|
||||
step=2;
|
||||
}else if(step==2){
|
||||
end(0,data);
|
||||
busy=0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool boardcast_updata::send_packet()
|
||||
{
|
||||
if(count_sent<data.size()){
|
||||
uint32_t addr=MCU_APP_ADDR_BASE+count_sent;
|
||||
int pack_size=240;
|
||||
myarray s;
|
||||
if(pack_size>data.size()-count_sent){
|
||||
pack_size=data.size()-count_sent;
|
||||
}
|
||||
s.append((addr)&0xff);
|
||||
s.append((addr>>8)&0xff);
|
||||
s.append((addr>>16)&0xff);
|
||||
s.append((addr>>24)&0xff);
|
||||
s+=data.mid(count_sent,pack_size);
|
||||
count_sent+=pack_size;
|
||||
send_data(0xfc,s,10);
|
||||
}
|
||||
if(count_sent<data.size()){
|
||||
return false;
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -4,6 +4,8 @@
|
||||
#include "prot/prot_slave.h"
|
||||
|
||||
|
||||
|
||||
// 从机检测命令
|
||||
class slave_check:public HandleSlave
|
||||
{
|
||||
public:
|
||||
@@ -13,4 +15,84 @@ public:
|
||||
void timeout();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// 获取检测结果命令
|
||||
class slave_result:public HandleSlave
|
||||
{
|
||||
public:
|
||||
slave_result():HandleSlave(){}
|
||||
int start(myarray data);
|
||||
int dolater(int cmd, myarray data);
|
||||
void timeout();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// 设置硬件版本号命令
|
||||
class slave_sethardver:public HandleSlave
|
||||
{
|
||||
public:
|
||||
slave_sethardver():HandleSlave(){}
|
||||
int start(myarray data);
|
||||
int dolater(int cmd, myarray data);
|
||||
void timeout();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// 设置电阻校准值命令
|
||||
class slave_setresver:public HandleSlave
|
||||
{
|
||||
public:
|
||||
slave_setresver():HandleSlave(){}
|
||||
int start(myarray data);
|
||||
int dolater(int cmd, myarray data);
|
||||
void timeout();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// 获取电阻值命令
|
||||
class slave_resvalue:public HandleSlave
|
||||
{
|
||||
public:
|
||||
slave_resvalue():HandleSlave(){}
|
||||
int start(myarray data);
|
||||
int dolater(int cmd, myarray data);
|
||||
void timeout();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 程序升级
|
||||
class boardcast_updata:public HandleBoardCast
|
||||
{
|
||||
public:
|
||||
boardcast_updata():HandleBoardCast(){step=0;count_sent=0;}
|
||||
int start(myarray data);
|
||||
int dolater(int cmd, myarray data);
|
||||
void timeout();
|
||||
bool send_packet();
|
||||
private:
|
||||
int step;
|
||||
myarray data;
|
||||
int count_sent;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // CMD_SLAVE_H
|
||||
|
Reference in New Issue
Block a user