|
|
@ -13,6 +13,10 @@ using namespace iflytop; |
|
|
|
} while (0) |
|
|
|
|
|
|
|
SocketCan::SocketCanError_t SocketCan::sendFrame(shared_ptr<SocketCanFrame> frame) { |
|
|
|
if (!m_canBusIsReady) { |
|
|
|
return kDeviceBusy; |
|
|
|
} |
|
|
|
|
|
|
|
if (frame == nullptr) { |
|
|
|
logger->error("frame is null"); |
|
|
|
return kParamError; |
|
|
@ -27,6 +31,10 @@ SocketCan::SocketCanError_t SocketCan::sendFrame(shared_ptr<SocketCanFrame> fram |
|
|
|
return writeFrame(canframe); |
|
|
|
} |
|
|
|
SocketCan::SocketCanError_t SocketCan::writeFrame(const canfd_frame_t &frame) { |
|
|
|
if (!m_canBusIsReady) { |
|
|
|
return kDeviceBusy; |
|
|
|
} |
|
|
|
|
|
|
|
setTxStateToTxing(frame); |
|
|
|
int ret = write(m_socketCanFd, &frame, frame.len + 8); |
|
|
|
if (ret != (frame.len + 8)) { |
|
|
@ -39,6 +47,15 @@ SocketCan::SocketCanError_t SocketCan::writeFrame(const canfd_frame_t &frame) { |
|
|
|
|
|
|
|
SocketCan::SocketCanError_t SocketCan::sendFrame(shared_ptr<SocketCanFrame> frame, int overtime) { |
|
|
|
tp_steady start = tu_steady().now(); |
|
|
|
|
|
|
|
while (tu_steady().elapsedTimeMs(start) < overtime && !m_canBusIsReady) { |
|
|
|
usleep(100); |
|
|
|
} |
|
|
|
|
|
|
|
if (!m_canBusIsReady) { |
|
|
|
return kOvertime; |
|
|
|
} |
|
|
|
|
|
|
|
while (tu_steady().elapsedTimeMs(start) < overtime && isTxing()) { |
|
|
|
usleep(100); |
|
|
|
} |
|
|
@ -61,6 +78,10 @@ bool SocketCan::isTxFrame(const canfd_frame_t &frame) { |
|
|
|
} |
|
|
|
|
|
|
|
SocketCan::SocketCanError_t SocketCan::sendFrame(string framestr) { |
|
|
|
if (!m_canBusIsReady) { |
|
|
|
return kOvertime; |
|
|
|
} |
|
|
|
|
|
|
|
struct canfd_frame frame = {0}; |
|
|
|
int required_mtu = 0; |
|
|
|
|
|
|
@ -117,6 +138,9 @@ void SocketCan::startListenThread() { |
|
|
|
*/ |
|
|
|
socketCanReadThreadLoop(); |
|
|
|
})); |
|
|
|
m_canBusIsReady = true; |
|
|
|
|
|
|
|
m_autoRestartThread.reset(new Thread("SocketCanAutoRestartThread", [this]() { monitorLoop(); })); |
|
|
|
} |
|
|
|
void SocketCan::endListenThread() { |
|
|
|
logger->info("endListenThread"); |
|
|
@ -386,8 +410,7 @@ void SocketCan::socketCanReadThreadLoop() { |
|
|
|
// /usr/include/linux/can/error.h
|
|
|
|
// x can-bus error event 20000004,0004000000000086
|
|
|
|
logger->error("rx can-bus error event {:x},{}", canframe.can_id, StringUtils().bytesToString(canframe.data, canframe.len)); |
|
|
|
// m_canTriggerError = true;
|
|
|
|
// socketcanInitialize();
|
|
|
|
|
|
|
|
unsetTxStateToTxing(); |
|
|
|
// exit(-1);
|
|
|
|
break; |
|
|
@ -400,4 +423,48 @@ void SocketCan::socketCanReadThreadLoop() { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
m_canTriggerError = true; |
|
|
|
m_canBusIsReady = false; |
|
|
|
} |
|
|
|
|
|
|
|
void SocketCan::monitorLoop() { |
|
|
|
ThisThread thisThread; |
|
|
|
while (!thisThread.getExitFlag()) { |
|
|
|
if (m_canTriggerError) { |
|
|
|
// 尝试恢复CAN总线
|
|
|
|
logger->warn("try to recover can bus............................................"); |
|
|
|
if (m_thread) { |
|
|
|
m_thread->join(); |
|
|
|
m_thread = nullptr; |
|
|
|
} |
|
|
|
logger->warn("close can bus fd:{}", m_socketCanFd); |
|
|
|
|
|
|
|
close(m_socketCanFd); |
|
|
|
m_socketCanFd = -1; |
|
|
|
|
|
|
|
{ |
|
|
|
lock_guard<recursive_mutex> lock(m_txState.lock); |
|
|
|
memset(&m_txState.txbuf, 0x00, sizeof(m_txState.txbuf)); |
|
|
|
m_txState.txState = TxState_t::kTxIdle; |
|
|
|
m_txState.txAckCount = 0; |
|
|
|
m_txState.txLoopMessageRxTicket = zsteady_clock().now(); |
|
|
|
} |
|
|
|
|
|
|
|
logger->warn("re init can bus"); |
|
|
|
socketcanInitialize(); |
|
|
|
|
|
|
|
m_thread.reset(new Thread("SocketCanThread", [this]() { |
|
|
|
usleep(10 * 1000); |
|
|
|
socketCanReadThreadLoop(); |
|
|
|
})); |
|
|
|
|
|
|
|
m_canTriggerError = false; |
|
|
|
m_canBusIsReady = true; |
|
|
|
|
|
|
|
logger->warn("recover can bus ok............................................"); |
|
|
|
} |
|
|
|
|
|
|
|
thisThread.sleepForMs(30); |
|
|
|
} |
|
|
|
} |