飞凌嵌入式
直播中

jf_37860120

5年用户 9经验值
擅长:嵌入式技术
私信 关注
[技术]

飞凌嵌入式OK153-S开发板 CAN 通信测试

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

其中 CAN0 只负责发送数据,CAN1 负责接收打印数据

生成程序如下

can01.png

运行结果如下:
can01sr.png

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:
    // static Class_Device_Can* getClassHandle()
    // {
    //     if(handle == nullptr)
    //     {
    //         handle = new Class_Device_Can();
    //         return handle;
    //     }
    //     else
    //     {
    //         return handle;
    //     }
    // }
    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:

    //static Class_Device_Can* handle;
    char have_prepare_data;
    char *prepare_data;
    int working = 0;//=0不工作,=1工作,=-1,退出
    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 // CLASS_DEVICE_CAN_H

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)
{
    // read config
    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;
    }


    // 填充socket地址结构
    struct sockaddr_can addr;
    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;
    // 绑定到socket
    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()
{
    //read config

    //--------------------------------------
    // struct can_filter rfilter[2];

    // rfilter[0].can_id  = 0x123;
    // rfilter[0].can_mask = 0x7FF;

    // rfilter[1].can_id  = 0x456;
    // rfilter[1].can_mask = 0x7FF;

    // if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)) < 0) {
    //     perror("Error in setsockopt");
    //     return -3;
    // }
    // 设置接收过滤器,只接收ID为0x123的消息
    // struct can_filter rfilter;
    // rfilter.can_id  = 0x14;  // CAN ID
    // rfilter.can_mask = CAN_SFF_MASK; // CAN Mask
    // setsockopt(socketCan, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
    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
    {
        // 处理接收到的CAN帧
        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();
                            //events[i].events = 0;
                        }
                        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{
                                // working = 0;
                            }
                        }
                        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);
            }
        }

    }//end while()

    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)
{
    //cout <<std::endl<<std::endl<< "sendby_can! "<<std::endl<<std::flush;
    have_prepare_data = 1;
    prepare_data = data;
}




更多回帖

发帖
×
20
完善资料,
赚取积分