提问者:小点点

在while循环中读取CAN数据的更有效方法


我有3个设备通过CAN接口发送8字节的数据。 要从CAN中读取缓冲区,我使用了一个while循环,如下所示:

void CanServer::ReadFromCAN()
{
    data_from_buffer_.clear();
    can_frame frame;
    read_can_port_ = read(soc_, &frame, sizeof(struct can_frame));
    if (read_can_port_ < 0) return;
    id_ = frame.can_id&0x1FFFFFFF;
    dlc_ = frame.can_dlc;
    for (const auto& byte : frame.data) data_from_buffer_.push_back(byte);
}

while(ros::ok())
{
    std_msgs::Int32MultiArray tachometer_array;
    std::vector<__u8> data_from_can;


    /***
     * Read for the Radar1
     */

    this->ReadFromCAN();
    if (read_can_port_ < 0) continue;
    //ROS_INFO("Read from CAN");
    if (id_ == can_id::RadarFrame1)
    {
        for (int i = 0; i < dlc_; i++)
        {
            radar1_bytes_[i] = data_from_buffer_[i];
            radar1_buffer_.push_back(data_from_buffer_[i]);
        }
        if (IsMagicWord(radar1_bytes_, 0))
        {
            frame_id = "radar1_link";
            this->PulbishRadarPCL(frame_id, radar1_pub_, radar1_buffer_, 0);
            radar1_buffer_.clear();
            canFrame_.can_dlc = 0;
        }
    }

    if (id_ == can_id::RadarFrame2)
    {
        for (int i = 0; i < dlc_; i++)
        {
            radar2_bytes_[i] = data_from_buffer_[i];
            radar2_buffer_.push_back(data_from_buffer_[i]);
        }
        if (IsMagicWord(radar2_bytes_, 1))
        {
            frame_id = "radar2_link";
            this->PulbishRadarPCL(frame_id, radar2_pub_, radar2_buffer_, 1);
            radar2_buffer_.clear();
            canFrame_.can_dlc = 0;
        }
    }

    if (id_ == can_id::RadarFrame3)
    {
        for (int i = 0; i < dlc_; i++)
        {
            radar3_bytes_[i] = data_from_buffer_[i];
            radar3_buffer_.push_back(data_from_buffer_[i]);
        }
        if (IsMagicWord(radar3_bytes_, 2))
        {
            frame_id = "radar3_link";
            this->PulbishRadarPCL(frame_id, radar3_pub_, radar3_buffer_, 2);
            radar3_buffer_.clear();
            canFrame_.can_dlc = 0;
        }
    }
    

    rate.sleep();
}

其中rate.sleep()类似于C++中的sleep()函数。 现在,我正在运行这个while循环在5 MHz,但我认为这是一个过度,我得到几乎100%的CPU使用率在一个1内核。 我试图玩弄延迟时间,但我认为这是高度低效的,我想知道有没有其他方法来处理这个问题?


共1个答案

匿名用户

原来投票是你需要的。 下面是我的例子。

>

  • 首先,从创建pollfd结构; Linux中的头。 我已经决定创建一个类成员,但是您可以随意创建:

     pollfd poll_;
     poll_.fd = soc_;
     poll_.events = POLLIN;
     poll_.revents = 0;
    

    在这里,soc_是一个套接字,pollin表示要从套接字读取。

    然后,在我的while循环中,我只是在while循环的开头使用了这个函数,而不是延迟:

     poll_int = poll(&poll_, 1, 100);
     if (poll_int <= 0) continue;
    

    所以poll()函数返回值1,如果读取成功并且我超时100ms(只是一个随机数,我知道数据以更高的速率来)

    这样,只有当poll返回大于0的值时,您才会从socket读取数据。

    结果? 如果您想在套接字流中添加更多数据,poll将为您进行优化,因此这是一种可扩展的读取CAN总线之类数据的方式。