添加广播方式升级

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

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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字节

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -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
View 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
View 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
View 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() << "Cant 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
View 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

View File

@@ -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);

View File

@@ -22,6 +22,9 @@ public:
{
this->irq_fun = fun;
}
virtual int write(int dst,myarray data){
return write(data);
}
protected:
irq_cb irq_fun;