#include "interface/if_can.h" #include #include "QTimer" #include "base/crc.h" #include #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_old; typedef struct { uint32_t SegNum : 8; uint32_t Reserve0 : 2; uint32_t ACK : 1; uint32_t FunClass : 6; uint32_t SegFlag : 2; uint32_t destMACID : 5; uint32_t srcMACID : 5; uint32_t Reserve1 : 3; } YeCanID_st; typedef union { uint32_t Exide; YeCanID_st yecanid; YeCanID_st_old yecanid_old; } 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; recv_cb_fun=nullptr; } can_host::~can_host() { if(can_ !=nullptr){ delete can_; } if(timer_ !=nullptr){ delete timer_; } } // 用于返回指定地址的从机对象 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:"< /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; uint8_t dst_addr; uint8_t seg_flag; int seg_num; if(frame_id.yecanid.Reserve0==0){ slave_addr = frame_id.yecanid_old.srcMACID; dst_addr = frame_id.yecanid_old.destMACID; seg_flag = frame_id.yecanid_old.SegFlag; seg_num = frame_id.yecanid_old.SegNum; }else{ slave_addr = frame_id.yecanid.srcMACID; dst_addr = frame_id.yecanid.destMACID; seg_flag = frame_id.yecanid.SegFlag; seg_num = frame_id.yecanid.SegNum; } can_slave &slave = get_slave_by_addr(slave_addr); if (seg_flag == 0x00){ // 不分段 slave.clear(); slave.append(payload); // qDebug()<<"can recv from:"< addrs, QByteArray data) { for (int i = 0; i < addrs.size(); i++) append(addrs[i], 1, data); } void can_host::append(uint8_t addr, uint8_t fun_class, QByteArray data) { YeCanID_un frameId; frameId.Exide = 0; frameId.yecanid_old.destMACID = addr; frameId.yecanid_old.srcMACID = 0; frameId.yecanid_old.FunClass = fun_class; frameId.yecanid_old.SegFlag = 0; frameId.yecanid_old.SegNum = 0; // frameId.yecanid.Reserve0=1;// 使用新协议 // 单包发送 if (data.size() <= 8) { frameId.yecanid_old.SegFlag = 0x0; frameId.yecanid_old.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_old.SegFlag = 0x1; } else if (data.size() > 8) { frameId.yecanid_old.SegFlag = 0x2; } else { frameId.yecanid_old.SegFlag = 0x3; } frameId.yecanid_old.SegNum = (uint8_t)i; QCanBusFrame frame = QCanBusFrame(frameId.Exide, data.left(8)); while (can_->writeFrame(frame) != true) { // qDebug("wait for written."); 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);