Linux CAN socketCAN—文件传输的可靠性如何
我想将文件(每个大约4MB的mp3)发送到通过CAN连接的设备。我正在用Linux机器和ESP32进行测试。问题在于并非所有数据都到达目的地 我使用socketCAN和UCCB USB-CAN转换器从Linux机器发送 到ESP32,或在两个ESP32之间 从PC Linux发送到ESP32时,有时只保存1/3的mp3文件,在发送过程中,我运行了candump slcan0命令,看起来所有数据都在总线上,但ESP32没有看到一些帧 当我在两个ESP32之间发送数据时,例如4MB的数据,接收到的ESP32会得到大约398MB的数据,一些帧会丢失 我正在使用命令“slcand-o-c-f-s8/dev/ttyACM0 slcan0”来创建slcan0接口,尽管使用-s开关改变速度似乎不起作用 我是否遗漏了什么,或者CAN不适合这种高速、高负载操作?我想在canbus上安装30台设备,接收大约1GB的数据(mp3文件) 代码如下:Linux CAN socketCAN—文件传输的可靠性如何,linux,qt,can-bus,esp32,Linux,Qt,Can Bus,Esp32,我想将文件(每个大约4MB的mp3)发送到通过CAN连接的设备。我正在用Linux机器和ESP32进行测试。问题在于并非所有数据都到达目的地 我使用socketCAN和UCCB USB-CAN转换器从Linux机器发送 到ESP32,或在两个ESP32之间 从PC Linux发送到ESP32时,有时只保存1/3的mp3文件,在发送过程中,我运行了candump slcan0命令,看起来所有数据都在总线上,但ESP32没有看到一些帧 当我在两个ESP32之间发送数据时,例如4MB的数据,接收到的E
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;
}
}
CanMgr::CanMgr(QObject*父对象,LogModel*LogModel):QObject(父对象){
此->logModel=logModel;
发送计时器=新的QTimer(此);
发送定时器->设置单次显示(真);
发送定时器->设置间隔(1);
连接(发送计时器、&QTimer::timeout、this、&CanMgr::processQueue);
}
void CanMgr::connectDevice(){
QString错误字符串;
m_canDevice=QCanBus::instance()->createDevice(m_pluginName、m_socketName和&errorString);
如果(!m_canDevice){
qDebug()连接设备(){
qDebug()配置参数(QCanBusDevice::BitRateKey);
if(bitRate.isValid()){
qDebug()我会说显示您的I/O代码。添加到原始POST的代码您肯定丢失了一些东西,因为CAN没有数据包丢失。数据包仅在tx或rx缓冲区溢出时在节点内丢失。原因可能是发送器没有等待可用的缓冲区,或者是因为接收器没有在e下一个到达。@Lundin你说得对。例如,当我从ESP向PC发送数据时,我得到了所有的数据包(当然PC会更快)。当我从PC向ESP发送数据包时,ESP会收到1/4的数据包,因此我同意缓冲区溢出。但如何处理该问题,而不是:发送一个数据包(PC到ESP)-等待确认(ESP到PC)-发送另一个数据包(PC到ESP)