6 changed files with 65 additions and 548 deletions
-
7.project/cmake/target.cmake
-
2dep/iflytopcpp
-
49src/test/dump_can_driver_info.cpp
-
387src/test/socketcan.cpp
-
129src/test/socketcan.hpp
-
37src/test/test_can.cpp
@ -1 +1 @@ |
|||||
Subproject commit 5199d0a9ee175f8254d13ec9436be0f9f67e83d5 |
|
||||
|
Subproject commit f186de7700bf4550ce2420d1cd87d43a5a1bfc39 |
@ -0,0 +1,49 @@ |
|||||
|
#include <stdio.h>
|
||||
|
|
||||
|
#include "zlinuxcomponents/zmainhelper.hpp"
|
||||
|
//
|
||||
|
#include "iflytopcpp/core/spdlogfactory/logger.hpp"
|
||||
|
#include "iflytopcpp/core/thread/thread.hpp"
|
||||
|
#include "spdlog/spdlog.h"
|
||||
|
//
|
||||
|
|
||||
|
#include <linux/can.h>
|
||||
|
#include <linux/can/raw.h>
|
||||
|
#include <net/if.h>
|
||||
|
#include <stdio.h>
|
||||
|
#include <stdlib.h>
|
||||
|
#include <string.h>
|
||||
|
#include <sys/ioctl.h>
|
||||
|
#include <sys/socket.h>
|
||||
|
#include <unistd.h>
|
||||
|
|
||||
|
#include "iflytopcpp/core/driver/socketcan/socket_can.hpp"
|
||||
|
|
||||
|
using namespace iflytop; |
||||
|
using namespace core; |
||||
|
using namespace std; |
||||
|
using namespace clipp; |
||||
|
|
||||
|
class Main { |
||||
|
ENABLE_LOGGER(Main); |
||||
|
unique_ptr<Thread> thread; |
||||
|
shared_ptr<SocketCan> socketCan; |
||||
|
|
||||
|
public: |
||||
|
Main(/* args */) {} |
||||
|
~Main() {} |
||||
|
void run(int argc, char* argv[]) { |
||||
|
thread.reset(new Thread("main", [&]() { exit(main(argc, argv)); })); |
||||
|
while (true) sleep(1000); |
||||
|
} |
||||
|
void onSIGINT() { exit(0); } |
||||
|
int main(int argCount, char* argValues[]) { |
||||
|
if (argCount < 3) { |
||||
|
logger->info("Usage: {} canName canBaudrate", argValues[0]); |
||||
|
return 1; |
||||
|
} |
||||
|
SocketCan::dumpCanDriverInfo(argValues[1], atoi(argValues[2])); |
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
MAIN_ENTRY(); |
@ -1,387 +0,0 @@ |
|||||
#include "socketcan.hpp"
|
|
||||
|
|
||||
#include <linux/can.h>
|
|
||||
#include <linux/can/raw.h>
|
|
||||
|
|
||||
#include "iflytopcpp/core/components/stringutils.hpp"
|
|
||||
//
|
|
||||
using namespace iflytop; |
|
||||
#define CANID_DELIM '#'
|
|
||||
#define CC_DLC_DELIM '_'
|
|
||||
#define DATA_SEPERATOR '.'
|
|
||||
#define CAN_MAX_DLC 8
|
|
||||
#define CAN_MAX_RAW_DLC 15
|
|
||||
#define CAN_MAX_DLEN 8
|
|
||||
unsigned char asc2nibble(char c) { |
|
||||
if ((c >= '0') && (c <= '9')) return c - '0'; |
|
||||
if ((c >= 'A') && (c <= 'F')) return c - 'A' + 10; |
|
||||
if ((c >= 'a') && (c <= 'f')) return c - 'a' + 10; |
|
||||
return 16; /* error */ |
|
||||
} |
|
||||
|
|
||||
/*******************************************************************************
|
|
||||
* can_frame_t * |
|
||||
*******************************************************************************/ |
|
||||
|
|
||||
shared_ptr<CanFrame> CanFrame::createExtDataFrame(uint32_t id, uint8_t *data, size_t len) { |
|
||||
shared_ptr<CanFrame> canframe = make_shared<CanFrame>(); |
|
||||
if (len > 8) len = 8; |
|
||||
canframe->m_id = id; |
|
||||
canframe->m_canIdentifier = kextFrame; |
|
||||
canframe->m_canFrameType = kdataframe; |
|
||||
canframe->m_dlc = len; |
|
||||
memcpy(canframe->m_data, data, len); |
|
||||
return canframe; |
|
||||
} |
|
||||
|
|
||||
shared_ptr<CanFrame> CanFrame::createStdDataFrame(uint32_t id, uint8_t *data, size_t len) { |
|
||||
shared_ptr<CanFrame> canframe = make_shared<CanFrame>(); |
|
||||
if (len > 8) len = 8; |
|
||||
canframe->m_id = id; |
|
||||
canframe->m_canIdentifier = kstdFrame; |
|
||||
canframe->m_canFrameType = kdataframe; |
|
||||
canframe->m_dlc = len; |
|
||||
memcpy(canframe->m_data, data, len); |
|
||||
return canframe; |
|
||||
} |
|
||||
|
|
||||
shared_ptr<CanFrame> CanFrame::createExtRemoteFrame(uint32_t id) { |
|
||||
shared_ptr<CanFrame> canframe = make_shared<CanFrame>(); |
|
||||
canframe->m_id = id; |
|
||||
canframe->m_canIdentifier = kextFrame; |
|
||||
canframe->m_canFrameType = kremoteframe; |
|
||||
canframe->m_dlc = 0; |
|
||||
return canframe; |
|
||||
} |
|
||||
shared_ptr<CanFrame> CanFrame::createStdRemoteFrame(uint32_t id) { |
|
||||
shared_ptr<CanFrame> canframe = make_shared<CanFrame>(); |
|
||||
canframe->m_id = id; |
|
||||
canframe->m_canIdentifier = kstdFrame; |
|
||||
canframe->m_canFrameType = kremoteframe; |
|
||||
canframe->m_dlc = 0; |
|
||||
return canframe; |
|
||||
} |
|
||||
void CanFrame::setCanIdentifier(can_identifier_t canIdentifier) { this->m_canIdentifier = canIdentifier; } |
|
||||
void CanFrame::setFanFrameType(can_frame_type_t fanFrameType) { this->m_canFrameType = fanFrameType; } |
|
||||
void CanFrame::setId(uint32_t id) { this->m_id = id; } |
|
||||
|
|
||||
uint32_t CanFrame::getId() { return m_id; } |
|
||||
can_identifier_t CanFrame::getCanIdentifier() { return m_canIdentifier; } |
|
||||
can_frame_type_t CanFrame::getFanFrameType() { return m_canFrameType; } |
|
||||
|
|
||||
/*******************************************************************************
|
|
||||
* SocketCan * |
|
||||
*******************************************************************************/ |
|
||||
#if 0
|
|
||||
int s, nbytes; |
|
||||
struct sockaddr_can addr; |
|
||||
struct ifreq ifr; |
|
||||
struct can_frame frame[2] = {{0}}; |
|
||||
s = socket(PF_CAN, SOCK_RAW, CAN_RAW); |
|
||||
printf("send_s = %d\n", s); |
|
||||
strcpy(ifr.ifr_name, "can0"); |
|
||||
ioctl(s, SIOCGIFINDEX, &ifr); |
|
||||
addr.can_family = AF_CAN; |
|
||||
addr.can_ifindex = ifr.ifr_ifindex; |
|
||||
bind(s, (struct sockaddr *)&addr, sizeof(addr)); |
|
||||
|
|
||||
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0); |
|
||||
|
|
||||
frame[0].can_id = 0x11; |
|
||||
frame[0].can_dlc = 1; |
|
||||
frame[0].data[0] = 'Y'; |
|
||||
frame[1].can_id = 0x410; |
|
||||
frame[1].can_dlc = 1; |
|
||||
frame[1].data[0] = 'N'; |
|
||||
|
|
||||
while (1) { |
|
||||
nbytes = write(s, &frame[0], sizeof(frame[0])); |
|
||||
if (nbytes != sizeof(frame[0])) { |
|
||||
printf("Send Error frame[0]!\n"); |
|
||||
break; |
|
||||
} |
|
||||
|
|
||||
sleep(1); |
|
||||
|
|
||||
nbytes = write(s, &frame[1], sizeof(frame[1])); |
|
||||
if (nbytes != sizeof(frame[1])) { |
|
||||
printf("Send Error frame[1]!\n"); |
|
||||
break; |
|
||||
} |
|
||||
|
|
||||
sleep(1); |
|
||||
} |
|
||||
|
|
||||
close(s); |
|
||||
#endif
|
|
||||
|
|
||||
bool SocketCan::findCan(string canName) { return access(fmt::format("/sys/class/net/{}", canName).c_str(), F_OK) == 0; } |
|
||||
|
|
||||
bool SocketCan::initialize(string canName, int bitrate, vector<can_filter_t> filters) { |
|
||||
m_canName = canName; |
|
||||
if (findCan(canName) == false) { |
|
||||
logger->error("can {} not found", canName); |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
// setCanBitrate(canName, bitrate);
|
|
||||
|
|
||||
m_canfd = socket(PF_CAN, SOCK_RAW, CAN_RAW); |
|
||||
if (m_canfd < 0) { |
|
||||
logger->error("socket failed,{}", strerror(errno)); |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
struct ifreq ifr = {0}; |
|
||||
strcpy(ifr.ifr_name, canName.c_str()); |
|
||||
ioctl(m_canfd, SIOCGIFINDEX, &ifr); |
|
||||
|
|
||||
const int bufsize = 0; |
|
||||
if (setsockopt(m_canfd, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) != 0) { |
|
||||
logger->error("setsockopt SO_SNDBUF fail,{}", strerror(errno)); |
|
||||
return -1; |
|
||||
} |
|
||||
|
|
||||
struct sockaddr_can addr = {0}; |
|
||||
addr.can_family = AF_CAN; |
|
||||
addr.can_ifindex = ifr.ifr_ifindex; |
|
||||
if (bind(m_canfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { |
|
||||
logger->error("bind fail,{}", strerror(errno)); |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
if (!filters.empty()) { |
|
||||
if (setsockopt(m_canfd, SOL_CAN_RAW, CAN_RAW_FILTER, filters.data(), filters.size() * sizeof(struct can_filter)) != 0) { |
|
||||
logger->error("set filters fail,{}", strerror(errno)); |
|
||||
return false; |
|
||||
}; |
|
||||
} else { |
|
||||
can_filter_t filter = {0}; |
|
||||
filter.can_id = 0; |
|
||||
filter.can_mask = 0; |
|
||||
if (setsockopt(m_canfd, SOL_CAN_RAW, CAN_RAW_FILTER, &filter, sizeof(filter)) != 0) { |
|
||||
logger->error("set filters fail,{}", strerror(errno)); |
|
||||
return false; |
|
||||
}; |
|
||||
} |
|
||||
|
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
int SocketCan::sendFrame(shared_ptr<CanFrame> frame) { |
|
||||
if (frame == nullptr) { |
|
||||
logger->error("frame is null"); |
|
||||
return -1; |
|
||||
} |
|
||||
if (m_canfd < 0) { |
|
||||
logger->error("canfd is invalid"); |
|
||||
return -1; |
|
||||
} |
|
||||
|
|
||||
canfd_frame_t canframe = frame->getCanFrame(); |
|
||||
|
|
||||
int ret = write(m_canfd, &canframe, canframe.len + 8); |
|
||||
if (ret != (canframe.len + 8)) { |
|
||||
logger->error("write fail,{}", strerror(errno)); |
|
||||
return -1; |
|
||||
} |
|
||||
return 0; |
|
||||
} |
|
||||
#if 0
|
|
||||
struct canfd_frame { |
|
||||
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ |
|
||||
__u8 len; /* frame payload length in byte */ |
|
||||
__u8 flags; /* additional flags for CAN FD */ |
|
||||
__u8 __res0; /* reserved / padding */ |
|
||||
__u8 __res1; /* reserved / padding */ |
|
||||
__u8 data[CANFD_MAX_DLEN] __attribute__((aligned(8))); |
|
||||
}; |
|
||||
#endif
|
|
||||
|
|
||||
void SocketCan::startListen() { |
|
||||
m_thread.reset( //
|
|
||||
new Thread(fmt::format("SocketCan_{}_ListenThread", m_canName), //
|
|
||||
[this]() { |
|
||||
ThisThread thisThread; |
|
||||
fd_set readfds, readFileDescriptors; |
|
||||
FD_ZERO(&readFileDescriptors); |
|
||||
FD_SET(m_canfd, &readFileDescriptors); |
|
||||
|
|
||||
while (!thisThread.getExitFlag()) { |
|
||||
canfd_frame_t canframe; |
|
||||
struct canfd_frame frame; |
|
||||
|
|
||||
timeval waitTime; |
|
||||
waitTime.tv_sec = 3; |
|
||||
waitTime.tv_usec = 0; |
|
||||
|
|
||||
readfds = readFileDescriptors; |
|
||||
|
|
||||
int n = select(m_canfd + 1, &readfds, 0, 0, &waitTime); |
|
||||
logger->info("select.... {}", n); |
|
||||
if (n <= 0) { |
|
||||
continue; |
|
||||
} |
|
||||
|
|
||||
memset(&canframe, 0x00, sizeof(canframe)); |
|
||||
int ret = read(m_canfd, &canframe, sizeof(canframe)); |
|
||||
// if (ret != sizeof(canframe)) {
|
|
||||
// logger->error("read fail,{}", strerror(errno));
|
|
||||
// continue;
|
|
||||
// }
|
|
||||
|
|
||||
logger->info("RX({}):{}", ret, StringUtils().bytesToString((uint8_t *)&canframe, ret)); |
|
||||
} |
|
||||
})); |
|
||||
} |
|
||||
canfd_frame_t CanFrame::getCanFrame() { |
|
||||
canfd_frame_t frame; |
|
||||
#if 1
|
|
||||
memset(&frame, 0, sizeof(frame)); |
|
||||
|
|
||||
if (m_canIdentifier == kstdFrame) { |
|
||||
frame.can_id = (m_id & CAN_SFF_MASK); |
|
||||
} else { |
|
||||
frame.can_id = (m_id & CAN_EFF_MASK) | CAN_EFF_FLAG; |
|
||||
} |
|
||||
|
|
||||
if (m_canFrameType == kremoteframe) { |
|
||||
frame.can_id |= CAN_RTR_FLAG; |
|
||||
frame.len = m_dlc; |
|
||||
} else { |
|
||||
frame.len = m_dlc; |
|
||||
memcpy(frame.data, m_data, m_dlc); |
|
||||
} |
|
||||
#endif
|
|
||||
return frame; |
|
||||
} |
|
||||
|
|
||||
int SocketCan::parse_canframe(char *cs, struct canfd_frame *cf) { |
|
||||
/* documentation see lib.h */ |
|
||||
|
|
||||
int i, idx, dlen, len; |
|
||||
int maxdlen = CAN_MAX_DLEN; |
|
||||
int ret = CAN_MTU; |
|
||||
canid_t tmp; |
|
||||
|
|
||||
len = strlen(cs); |
|
||||
// printf("'%s' len %d\n", cs, len);
|
|
||||
|
|
||||
memset(cf, 0, sizeof(*cf)); /* init CAN FD frame, e.g. LEN = 0 */ |
|
||||
|
|
||||
if (len < 4) return 0; |
|
||||
|
|
||||
if (cs[3] == CANID_DELIM) { /* 3 digits */ |
|
||||
|
|
||||
idx = 4; |
|
||||
for (i = 0; i < 3; i++) { |
|
||||
if ((tmp = asc2nibble(cs[i])) > 0x0F) return 0; |
|
||||
cf->can_id |= (tmp << (2 - i) * 4); |
|
||||
} |
|
||||
|
|
||||
} else if (cs[8] == CANID_DELIM) { /* 8 digits */ |
|
||||
|
|
||||
idx = 9; |
|
||||
for (i = 0; i < 8; i++) { |
|
||||
if ((tmp = asc2nibble(cs[i])) > 0x0F) return 0; |
|
||||
cf->can_id |= (tmp << (7 - i) * 4); |
|
||||
} |
|
||||
if (!(cf->can_id & CAN_ERR_FLAG)) /* 8 digits but no errorframe? */ |
|
||||
cf->can_id |= CAN_EFF_FLAG; /* then it is an extended frame */ |
|
||||
|
|
||||
} else |
|
||||
return 0; |
|
||||
|
|
||||
if ((cs[idx] == 'R') || (cs[idx] == 'r')) { /* RTR frame */ |
|
||||
cf->can_id |= CAN_RTR_FLAG; |
|
||||
|
|
||||
/* check for optional DLC value for CAN 2.0B frames */ |
|
||||
if (cs[++idx] && (tmp = asc2nibble(cs[idx++])) <= CAN_MAX_DLEN) { |
|
||||
cf->len = tmp; |
|
||||
|
|
||||
/* check for optional raw DLC value for CAN 2.0B frames */ |
|
||||
if ((tmp == CAN_MAX_DLEN) && (cs[idx++] == CC_DLC_DELIM)) { |
|
||||
tmp = asc2nibble(cs[idx]); |
|
||||
if ((tmp > CAN_MAX_DLEN) && (tmp <= CAN_MAX_RAW_DLC)) { |
|
||||
struct can_frame *ccf = (struct can_frame *)cf; |
|
||||
|
|
||||
ccf->__res1 = tmp; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
if (cs[idx] == CANID_DELIM) { /* CAN FD frame escape char '##' */ |
|
||||
|
|
||||
maxdlen = CANFD_MAX_DLEN; |
|
||||
ret = CANFD_MTU; |
|
||||
|
|
||||
/* CAN FD frame <canid>##<flags><data>* */ |
|
||||
if ((tmp = asc2nibble(cs[idx + 1])) > 0x0F) return 0; |
|
||||
|
|
||||
cf->flags = tmp; |
|
||||
idx += 2; |
|
||||
} |
|
||||
|
|
||||
for (i = 0, dlen = 0; i < maxdlen; i++) { |
|
||||
if (cs[idx] == DATA_SEPERATOR) /* skip (optional) separator */ |
|
||||
idx++; |
|
||||
|
|
||||
if (idx >= len) /* end of string => end of data */ |
|
||||
break; |
|
||||
|
|
||||
if ((tmp = asc2nibble(cs[idx++])) > 0x0F) return 0; |
|
||||
cf->data[i] = (tmp << 4); |
|
||||
if ((tmp = asc2nibble(cs[idx++])) > 0x0F) return 0; |
|
||||
cf->data[i] |= tmp; |
|
||||
dlen++; |
|
||||
} |
|
||||
cf->len = dlen; |
|
||||
|
|
||||
/* check for extra DLC when having a Classic CAN with 8 bytes payload */ |
|
||||
if ((maxdlen == CAN_MAX_DLEN) && (dlen == CAN_MAX_DLEN) && (cs[idx++] == CC_DLC_DELIM)) { |
|
||||
unsigned char dlc = asc2nibble(cs[idx]); |
|
||||
|
|
||||
if ((dlc > CAN_MAX_DLEN) && (dlc <= CAN_MAX_RAW_DLC)) { |
|
||||
struct can_frame *ccf = (struct can_frame *)cf; |
|
||||
|
|
||||
ccf->__res1 = dlc; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
int SocketCan::sendFrame(string framestr) { |
|
||||
struct canfd_frame frame; |
|
||||
int required_mtu; |
|
||||
required_mtu = parse_canframe((char *)framestr.c_str(), &frame); |
|
||||
if (!required_mtu) { |
|
||||
logger->error("Wrong CAN-frame format!"); |
|
||||
return -1; |
|
||||
} |
|
||||
|
|
||||
if (required_mtu > (int)CAN_MTU) { |
|
||||
logger->error("CAN-FD frames not supported!"); |
|
||||
return -1; |
|
||||
} |
|
||||
logger->info("send frame:{} {} {} {} {} {}", required_mtu, frame.can_id, frame.len, frame.flags, frame.__res0, frame.__res1); |
|
||||
if (write(m_canfd, &frame, required_mtu) != required_mtu) { |
|
||||
logger->error("CAN-FD frames not supported!"); |
|
||||
return -1; |
|
||||
} |
|
||||
return 0; |
|
||||
} |
|
||||
|
|
||||
void SocketCan::dosystem(string cmd) { |
|
||||
logger->info("do cmd:{}", cmd); |
|
||||
system(cmd.c_str()); |
|
||||
} |
|
||||
|
|
||||
void SocketCan::setCanBitrate(string canName, int bitrate) { |
|
||||
logger->info("set can:{} bitrate:{}", canName, bitrate); |
|
||||
dosystem(fmt::format("ip link set {} down", canName)); |
|
||||
dosystem(fmt::format("ip link set {} type can bitrate {}", canName, bitrate)); |
|
||||
dosystem(fmt::format("ip link set {} up", canName)); |
|
||||
} |
|
@ -1,129 +0,0 @@ |
|||||
//
|
|
||||
// Created by zwsd
|
|
||||
//
|
|
||||
|
|
||||
#pragma once
|
|
||||
#include <linux/can.h>
|
|
||||
#include <linux/can/raw.h>
|
|
||||
#include <net/if.h>
|
|
||||
#include <stdio.h>
|
|
||||
#include <stdlib.h>
|
|
||||
#include <string.h>
|
|
||||
#include <sys/ioctl.h>
|
|
||||
#include <sys/socket.h>
|
|
||||
#include <unistd.h>
|
|
||||
|
|
||||
#include <fstream>
|
|
||||
#include <iostream>
|
|
||||
#include <list>
|
|
||||
#include <map>
|
|
||||
#include <memory>
|
|
||||
#include <set>
|
|
||||
#include <sstream>
|
|
||||
#include <string>
|
|
||||
#include <vector>
|
|
||||
|
|
||||
#include "iflytopcpp/core/basic/nod/nod.hpp"
|
|
||||
#include "iflytopcpp/core/spdlogfactory/logger.hpp"
|
|
||||
#include "iflytopcpp/core/thread/thread.hpp"
|
|
||||
|
|
||||
/**
|
|
||||
* @brief |
|
||||
* |
|
||||
* service: SocketCan |
|
||||
* |
|
||||
* 监听事件: |
|
||||
* 依赖状态: |
|
||||
* 依赖服务: |
|
||||
* 作用: |
|
||||
* |
|
||||
*/ |
|
||||
|
|
||||
namespace iflytop { |
|
||||
using namespace std; |
|
||||
using namespace core; |
|
||||
|
|
||||
/*******************************************************************************
|
|
||||
* CAN_FRAME * |
|
||||
*******************************************************************************/ |
|
||||
|
|
||||
typedef struct can_filter can_filter_t; |
|
||||
typedef struct canfd_frame canfd_frame_t; |
|
||||
typedef enum { |
|
||||
kstdFrame, |
|
||||
kextFrame, |
|
||||
} can_identifier_t; |
|
||||
|
|
||||
typedef enum { |
|
||||
kdataframe, |
|
||||
kremoteframe, |
|
||||
} can_frame_type_t; |
|
||||
|
|
||||
class CanFrame { |
|
||||
private: |
|
||||
uint32_t m_id = 0; |
|
||||
can_identifier_t m_canIdentifier = kstdFrame; |
|
||||
can_frame_type_t m_canFrameType = kdataframe; |
|
||||
uint8_t m_data[8] = {0}; |
|
||||
uint8_t m_dlc = 0; |
|
||||
|
|
||||
public: |
|
||||
static shared_ptr<CanFrame> createExtDataFrame(uint32_t id, uint8_t *data, size_t len); |
|
||||
static shared_ptr<CanFrame> createStdDataFrame(uint32_t id, uint8_t *data, size_t len); |
|
||||
static shared_ptr<CanFrame> createExtRemoteFrame(uint32_t id); |
|
||||
static shared_ptr<CanFrame> createStdRemoteFrame(uint32_t id); |
|
||||
|
|
||||
void setId(uint32_t id); |
|
||||
uint32_t getId(); |
|
||||
can_frame_type_t getFanFrameType(); |
|
||||
void setFanFrameType(can_frame_type_t fanFrameType); |
|
||||
can_identifier_t getCanIdentifier(); |
|
||||
void setCanIdentifier(can_identifier_t canIdentifier); |
|
||||
|
|
||||
canfd_frame_t getCanFrame(); |
|
||||
}; |
|
||||
|
|
||||
/*******************************************************************************
|
|
||||
* SocketCan * |
|
||||
*******************************************************************************/ |
|
||||
|
|
||||
class SocketCan { |
|
||||
ENABLE_LOGGER(SocketCan); |
|
||||
|
|
||||
string m_canName; |
|
||||
int m_canfd; |
|
||||
vector<can_filter_t> m_canfilters; |
|
||||
unique_ptr<Thread> m_thread; |
|
||||
|
|
||||
public: |
|
||||
nod::signal<void(shared_ptr<CanFrame> canframe)> signalOnFrame; |
|
||||
|
|
||||
public: |
|
||||
SocketCan(){}; |
|
||||
bool initialize(string canName, int bitrate, vector<can_filter_t> filters); |
|
||||
int sendFrame(shared_ptr<CanFrame> frame); |
|
||||
/**
|
|
||||
* @brief 发送can帧 |
|
||||
* |
|
||||
* @param frame |
|
||||
* frame="11111111#1122334455667788" ID=0x11111111,帧类型=数据帧,帧格式=扩展帧,数据长度=8,数据=1122334455667788 |
|
||||
* frame="111#1122334455667788" ID=0x111, 帧类型=数据帧,帧格式=标准帧,数据长度=8,数据=1122334455667788 |
|
||||
* frame="111#R" ID=0x111, 帧类型=远程帧,帧格式=标准帧,数据长度=0 |
|
||||
* frame="11111111#R" ID=0x11111111,帧类型=远程帧,帧格式=扩展帧,数据长度=0 |
|
||||
* @return int |
|
||||
*/ |
|
||||
int sendFrame(string frame); |
|
||||
void startListen(); |
|
||||
~SocketCan() { |
|
||||
if (m_canfd > 0) { |
|
||||
close(m_canfd); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
void dosystem(string cmd); |
|
||||
void setCanBitrate(string canName, int bitrate); |
|
||||
bool findCan(string canName); |
|
||||
int parse_canframe(char *cs, struct canfd_frame *cf); |
|
||||
}; |
|
||||
} // namespace iflytop
|
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue