此次发帖描述飞凌嵌入式的OK153-S开发板两路 CAN 通信测试。
通信测试为使用开发板上的两个 CAN 对接。

其中 CAN0 只负责发送数据,CAN1 负责接收打印数据
生成程序如下

运行结果如下:

can 读写代码
头文件
#ifndef CLASS_DEVICE_CAN_H
#define CLASS_DEVICE_CAN_H
#include <thread>
#include <signal.h>
#include <iomanip>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/sockios.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <net/if.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <cstring>
#include <sys/epoll.h>
using namespace std;
class Class_Device_Can
{
public:
Class_Device_Can();
int running(char* dev,unsigned int canID);
int set_can_filter();
int reconfig_device();
void stop_thread();
void sendby_can(char *data);
private:
char have_prepare_data;
char *prepare_data;
int working = 0;
int fdEp = -1;
int socketCan = 0;
int epollerrorCount = 0;
__u32 can_id = 0x00;
__u8 can_dlc = 0x00;
int can_baudrate;
can_frame baseframe;
unsigned int get_framecount = 0;
unsigned int send_framecount = 0;
int readCanData();
int init_device(int t=0);
};
#endif
cpp实现:
#include "class_device_can.h"
#define MAX_EVENTS 10
static char* devName = nullptr;
static char savetime[20] = {0};
Class_Device_Can::Class_Device_Can()
{
get_framecount = 0;
send_framecount = 0;
can_id = 0x00;
can_dlc = 0x00;
working = 0;
}
int Class_Device_Can::init_device(int canID)
{
if(canID != -1){
close(socketCan);
}
else {
close(socketCan);
}
can_id = canID;
can_dlc = 0x08;
can_baudrate = 1000;
system("ip link set can0 down");
system("ip link set can0 type can bitrate 100000");
system("ip -detail link show can0");
system("ip link set can0 up");
cout<<"Class_Device_Can::init_device can_id :0x"<<std::hex<<static_cast<int>(can_id)<<std::endl<<std::flush;
cout<<"Class_Device_Can::init_device can_dlc :"<<static_cast<int>(can_dlc)<<std::endl<<std::flush;
cout<<"Class_Device_Can::init_device can_baudrate:"<<std::dec<<can_baudrate<<std::endl<<std::flush;
socketCan = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (socketCan < 0) {
cout << "Error while creating socketCan" << std::endl<<std::flush;
return -1;
}
else{
cout<<"creating socketCan OK"<<std::endl<<std::flush;
}
struct ifreq ifr;
strcpy(ifr.ifr_name, devName);
if (ioctl(socketCan, SIOCGIFINDEX, &ifr) < 0) {
cout << "can Error while getting interface index" << std::endl<<std::flush;
close(socketCan);
return -1;
}
else
{
fcntl(socketCan, F_SETFL, O_NONBLOCK);
cout<<"can getting interface index OK"<<std::endl<<std::flush;
}
struct sockaddr_can addr;
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(socketCan, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
cout << "socketCan Error while binding socket" << std::endl<<std::flush;
close(socketCan);
return -1;
}
else
{
baseframe.can_id = can_id;
baseframe.can_dlc = can_dlc;
cout<<"socketCan baseframe.can_id=0x"<<std::hex<<static_cast<int>(baseframe.can_id)<<std::endl<<std::flush;
cout<<"socketCan baseframe.can_dlc="<<std::dec<<static_cast<int>(baseframe.can_dlc)<<std::endl<<std::flush;
cout<<"binding socketCan OK"<<std::endl<<std::flush;
}
fdEp = -1;
fdEp = epoll_create(MAX_EVENTS);
epoll_event eve;
eve.data.fd = socketCan;
eve.events = EPOLLIN ;
int ret = epoll_ctl(fdEp, EPOLL_CTL_ADD, socketCan, &eve);
if(ret == -1) {
close(socketCan);
cout<<"epoll_ctl ERROR"<<std::endl<<std::flush;
fdEp = -1;
}
else {
cout<<"epoll_ctl OK"<<std::endl<<std::flush;
struct can_frame received_frame;
ssize_t nbytes = read(socketCan, &received_frame, sizeof(received_frame));
if (nbytes < 0) {
cout<< "Error while reading from socketCan" << std::endl;
}
else if(nbytes == 0){
cout<<"nbytes == 0 "<<endl;
}
else if(nbytes > 0){
cout<<"nbytes = "<<nbytes<<endl;
}
}
return 1;
}
int Class_Device_Can::reconfig_device()
{
working = 0;
return 1;
}
int Class_Device_Can::set_can_filter()
{
return 1;
}
int Class_Device_Can::readCanData()
{
struct can_frame received_frame;
ssize_t nbytes = read(socketCan, &received_frame, sizeof(received_frame));
if (nbytes < 0) {
std::cerr << devName <<"Error while reading from socketCan" << std::endl;
return -1;
}
else if(nbytes == 0){
std::cerr << devName <<"reading from socketCan data !" << std::endl;
return 0;
}
else
{
get_framecount++;
string str_savedata = " can read from ";
std::stringstream hexStream;
hexStream <<"0x";
hexStream << std::hex << std::uppercase << received_frame.can_id;
hexStream <<":";
hexStream << std::hex << static_cast<int>(received_frame.data[0]);
hexStream << std::hex << static_cast<int>(received_frame.data[1]);
hexStream << std::hex << static_cast<int>(received_frame.data[2]);
hexStream << std::hex << static_cast<int>(received_frame.data[3]);
hexStream << std::hex << static_cast<int>(received_frame.data[4]);
hexStream << std::hex << static_cast<int>(received_frame.data[5]);
hexStream << std::hex << static_cast<int>(received_frame.data[6]);
hexStream << std::hex << static_cast<int>(received_frame.data[7]);
str_savedata.append(hexStream.str());
std::cout << std::endl;
std::cout <<str_savedata<< std::endl;
std::cout << std::endl;
std::cout << std::endl;
return received_frame.can_id;
}
return 0;
}
int Class_Device_Can::running(char* dev,unsigned int canID)
{
devName = dev;
if(init_device(canID) > 0){
working = 1;
}
else {
working = -1;
}
int eventCount = 0;
epoll_event events[MAX_EVENTS];
while(working >= 0)
{
if(working > 0)
{
eventCount = epoll_wait(fdEp, events, MAX_EVENTS, 1);
if (eventCount == -1) {
cout << "exit : eventCount == -1 "<<std::endl<<std::flush;
working = 0;
break;
}else if (eventCount == 0) {
if(have_prepare_data > 0)
{
baseframe.data[0] = '\0';
baseframe.data[1] = '\0';
baseframe.data[2] = '\0';
baseframe.data[3] = '\0';
baseframe.data[4] = '\0';
baseframe.data[5] = '\0';
baseframe.data[6] = '\0';
baseframe.data[7] = '\0';
std::cout<<"can send data:";
for (int var = 0; var < baseframe.can_dlc; ++var) {
if(var < 8){
baseframe.data[var] = prepare_data[var];
std::cout<<std::hex<<static_cast<int>(baseframe.data[var])<<" "<<std::flush;
}
}
std::cout<<" "<<endl<<endl;
if (write(socketCan, &baseframe, 16) < 0) {
std::cout << "Error while writing to socketCan " << std::endl;
have_prepare_data = 0;
}
else
have_prepare_data = 0;
}
else{
}
}else{
cout << "eventCount = "<<eventCount<<std::endl;
for (int i = 0; i < eventCount; i++) {
if (events[i].data.fd == socketCan) {
if(events[i].events & EPOLLIN)
{
cout << "can get data ,events="<<events[i].events<<std::endl;
readCanData();
}
else if(events[i].events & EPOLLERR){
cout << "can get error ! "<<std::hex<<events[i].events<<std::endl;
cout<<std::dec<<" "<<std::endl;
if(epollerrorCount < 3)
epollerrorCount++;
else{
}
}
else {
cout << "can unknow event: "<<events[i].events<<std::endl;
}
}
break;
}
if(have_prepare_data > 0)
{
baseframe.data[0] = '\0';
baseframe.data[1] = '\0';
baseframe.data[2] = '\0';
baseframe.data[3] = '\0';
baseframe.data[4] = '\0';
baseframe.data[5] = '\0';
baseframe.data[6] = '\0';
baseframe.data[7] = '\0';
for (int var = 0; var < baseframe.can_dlc; ++var) {
if(var < 8){
baseframe.data[var] = prepare_data[var];
std::cout<<"baseframe.data["<<var<<"]"<<static_cast<int>(baseframe.data[var])<< std::endl;
}
}
if (write(socketCan, &baseframe, 16) < 0) {
std::cout << "Error while writing to socketCan " << std::endl;
have_prepare_data = 0;
}
else
have_prepare_data = 0;
}
}
}
else
{
if(init_device(0) > 0){
working = 1;
}
else {
cout << "restart task can ... "<<std::endl<<std::flush;
working = 0;
sleep(2);
}
}
}
close(socketCan);
cout << "Task can stoped !"<<std::endl<<std::flush;
return working;
}
void Class_Device_Can::stop_thread()
{
working = -1;
}
void Class_Device_Can::sendby_can(char *data)
{
have_prepare_data = 1;
prepare_data = data;
}