CAN socketCAN - насколько надежна передача файлов - PullRequest
0 голосов
/ 05 февраля 2020

Я хочу отправлять файлы (mp3 по 4 МБ каждый) на устройства, подключенные через CAN. Я тестирую с Linux машиной и ESP32. Проблема в том, что не все данные поступают в пункт назначения.

Я отправляю с Linux устройства, используя конвертер socketCAN и UCCB USB-CAN https://www.tindie.com/products/lll7/can-usb-converter-uccb/ в ESP32 или между двумя ESP32.

При отправке из P C Linux в ESP32, иногда сохраняется только 1/3 файла mp3, во время отправки у меня работает команда candump slcan0, и похоже, что все данные находятся на шине, но ESP32 не видит некоторые кадры.

Когда я посылаю между двумя ESP32, например 4 МБ данных, при получении ESP32 получается около 3,98 МБ данных, некоторые кадры теряются.

Я использую команду "slcand -o - c -f -s8 / dev / ttyACM0 slcan0 "для создания интерфейса slcan0, хотя изменение скорости с помощью ключа -s не работает.

Я что-то упустил или CAN не подходит для такой высокой скорости, операции с высокой нагрузкой? Я хочу иметь 30 устройств на CANBUS, которые получают около 1 ГБ данных (mp3-файлы)

код ниже:

CanMgr::CanMgr(QObject *parent,LogModel *logModel):QObject(parent) {
    this->logModel=logModel;

    send_timer=new QTimer(this);
    send_timer->setSingleShot(true);
    send_timer->setInterval(1);
    connect(send_timer,&QTimer::timeout,this,&CanMgr::processQueue);
}
void CanMgr::connectDevice() {
    QString errorString;
    m_canDevice = QCanBus::instance()->createDevice(m_pluginName,m_socketName,&errorString);

    if (!m_canDevice) {
        qDebug()<<QString("Error creating device '%1', reason: '%2'").arg(m_pluginName).arg(errorString);
        return;
    }

    m_numberFramesWritten = 0;

    connect(m_canDevice, &QCanBusDevice::errorOccurred, this, &CanMgr::processErrors);
    connect(m_canDevice, &QCanBusDevice::framesReceived, this, &CanMgr::processReceivedFrames);
    connect(m_canDevice, &QCanBusDevice::framesWritten, this, &CanMgr::processFramesWritten);
    connect(m_canDevice, &QCanBusDevice::stateChanged,this, &CanMgr::stateChanged);


    m_canDevice->setConfigurationParameter(QCanBusDevice::BitRateKey,"250000");
    if (!m_canDevice->connectDevice()) {
        qDebug()<<tr("Connection error: %1").arg(m_canDevice->errorString());

        delete m_canDevice;
        m_canDevice = nullptr;
    } else {

        QVariant bitRate = m_canDevice->configurationParameter(QCanBusDevice::BitRateKey);
        if (bitRate.isValid()) {
            qDebug()<<tr("Plugin: %1, connected to %2 at %3 kBit/s").arg(m_pluginName).arg(m_socketName).arg(bitRate.toInt() / 1000);
        } else {
            qDebug()<<tr("Plugin: %1, connected to %2").arg(m_pluginName).arg(m_socketName);
        }
    }
}
void CanMgr::sendFileContent(QByteArray data) {
    quint32 frameId = 0;
    quint32 dev_id=2;
    quint32 cmd_id=0;
    frameId=(dev_id<<16) | cmd_id;

    m_canDevice->clear();


    QByteArray size=Helper::byteArrFromInt((quint32)data.size(),8);
    qDebug()<<"CanMgr::sendFileContent file size in bytes:"<<Helper::printHex(size);

    QCanBusFrame frame = QCanBusFrame(frameId,size);
    frame.setExtendedFrameFormat(true);
    qDebug()<<"frame data:"<<frame.toString()<<" stat:"<<m_canDevice->state();
    queue.append(frame);

    frameId = 0;
    dev_id=2;
    cmd_id=1;

    frameId=(dev_id<<16) | cmd_id;

    for(int i=0;i<data.size();i+=8) {

        QCanBusFrame frame = QCanBusFrame(frameId, data.mid(i,8));
        frame.setExtendedFrameFormat(true);
        queue.append(frame);
    }

    frameId = 0;
    dev_id=2;
    cmd_id=2;
    frameId=(dev_id<<16) | cmd_id;


    frame = QCanBusFrame(frameId, size);
    frame.setExtendedFrameFormat(true);
    queue.append(frame);

    process_frame=false;
    send_timer->start();
}
void CanMgr::processQueue() {
    if(queue.isEmpty()) {
        qDebug()<<"CanMgr::processQueu queue empty";
        return;
    }
    if(process_frame) {
        ;
    }
    else {
        curr_frame=queue.dequeue();
        process_frame=true;
    }
    qDebug()<<"CanMgr::processQueue frame data:"<<curr_frame.toString()<<" towrite:"<<m_canDevice->framesToWrite()<<" left:"<<queue.count();

    m_canDevice->writeFrame(curr_frame);
}
void CanMgr::processFramesWritten(qint64 count) {
    qDebug()<<"CanMgr::processFramesWritten count:"<<count;
    process_frame=false;
    this->processQueue();
}
QString CanMgr::processErrors(QCanBusDevice::CanBusError error) const
{
    QString err_str;
    switch (error) {
    case QCanBusDevice::ReadError:
    case QCanBusDevice::WriteError:
    case QCanBusDevice::ConnectionError:
    case QCanBusDevice::ConfigurationError:
    case QCanBusDevice::UnknownError:
        err_str= m_canDevice->errorString();
        qDebug()<<"Error:"<<err_str;
        send_timer->start();
        return err_str;
        break;
    default:
        break;
    }
}

Best,

Marek

...