• 【socketCAN错误】write: No buffer space available


    前言

    错误

    write: No buffer space available
    write(s, &frame, sizeof(struct can_frame)) 的输出结果为-1

    原因

    由于缓冲队列空间不足;
    sudo su
    root@super:/sys/class/net/can1# cat tx_queue_len
    10
    root@super:/sys/class/net/can1# echo 1000 > tx_queue_len
    root@super:/sys/class/net/can1# cat tx_queue_len
    1000
    su user

     重启之后, tx_queue_len又回到默认值;

     调试之后发现主要是两个错误引起的:

    1) 数据转报文数据的时候,不够心细,有个错误;

    2) 红绿灯检测项目代码中,CAN模块在detector.c文件中,之前数据的报文还没有发送完成,新的数据已经开始操作,会改变原来的报文数据,故需要在新的数据初始化之前,有一段时间间隔再进行初始化;最开始发现是因为如果每次读取图片之前运行包含if ...break...的代码就正常收发,私以为此处这个if语句就类似于一个时间缓冲;

    3)修改CAN模块代码到sr/image.c中,方便用于之后通过camera处理数据,然后也出现了同样的错误,猜想也是时间间隔的问题,最后将usleep放在tfl_can.c中can_tfl函数数据初始化之前,就可以正常运行;

    char buf[5][8] = {0};

    pro code

    // typedef struct{
    //     unsigned int color; // 0-unknown, 1-green, 2-yellow, 3-red, 4-off;
    //     unsigned int type; // 0-unknown, 1-round, 2-left, 3-right, 4-Uturn, 5-bicycle, 6-pedestrain;
    //     unsigned int xpos; // 0-1280, image width;
    //     unsigned int level; // 0-3, 0-lowest, 3-highest;
    //     unsigned int total; // total num of object.
    //     unsigned int rlcnt; // Rolling Count, 0<->3.
    // } TFL;
    
    int roll_count = 0;
    void can_mdl(TFL* data)
    {
        int s;
        can_init(&s);
        can_tfl(s, data);
        close(s);
    }
    void can_detections(image im, detection *dets, int num, float thresh, int classes)
    {
        usleep(10);  // OK.
        TFL candata[10] = {0};
        // printf("-----------------------------roll count: %d\n", roll_count);
        for(int i=0; i<num; ++i){
            int class = -1;
            float max_prob = 0;
            for(int j=0; j<classes; ++j){
                float prob = dets[i].prob[j];
                if(prob > thresh){
                      if(class < 0){
                            class = j;
                            max_prob = prob;
                      }
                      else if(prob > max_prob){
                          class = j;
                          max_prob = prob;
                      }
                }
            }
            if(class<0){
                for(int j=0; j<classes; ++j){
                    float prob = dets[i].prob[j];
                    if(prob > max_prob){
                        class = j;
                        max_prob = prob;
                    }
                } 
            } 
            // dets[i], class, max_prob
            box b = dets[i].bbox;
            int left  = (b.x-b.w/2.)*im.w;
            int right = (b.x+b.w/2.)*im.w;
            int top   = (b.y-b.h/2.)*im.h;
            int bot   = (b.y+b.h/2.)*im.h;
    
            if(left < 0) left = 0;
            if(right > im.w-1) right = im.w-1;
            if(top < 0) top = 0;
            if(bot > im.h-1) bot = im.h-1;
            // printf("bbox(left, right, top, bot): %d %d %d %d\n", left, right, top, bot);
            // color
            if(class==0 || class==4 || class==8) candata[i].color = 1; // 1-green
            else if(class==1 || class==5 || class==9) candata[i].color = 3; // 3-red
            else if(class==2 || class==6 || class==10) candata[i].color = 2; // 2-yellow
            else if(class==3 || class==7 || class==11) candata[i].color = 4; // 4-off
            // type
            if(class==0 || class==1 || class==2 || class==3) candata[i].type = 1; // 1-round
            else if(class==4 || class==5 || class==6 || class==7) candata[i].type = 2; // 2-left
            else if(class==8 || class==9 || class==10 || class==11) candata[i].type = 5; // 5-bicycle
            // xpos
            candata[i].xpos  = (left+right)*0.5;
            // level
            if(max_prob >70) candata[i].level = 3;
            else if(max_prob > 50) candata[i].level = 2;
            else if(max_prob > 30) candata[i].level = 1;
            else candata[i].level = 0;
            // total
            // candata[i].total = num;
            // candata[i].rlcnt = roll_count;
        }
        for (int i=0; i<10; i++) {
            candata[i].total = num;
            candata[i].rlcnt = roll_count;
        }
        if(roll_count==3) roll_count = 0;
        else roll_count++;
        // CAN
        // usleep(100);  // not OK.
        TFL* tfldata = candata;
        can_mdl(tfldata);
        // int s;
        // can_init(&s);
        // can_tfl(s, tfldata);
        // close(s);
    }
    View Code

     tfl_can.c

    void can_tfl(int s, TFL* data)
    {
        char buf[5][8] = {0};
        buf[0][7] = (data->total)<<2;
        for(int i=0; i<5; i++)
        {
            buf[i][0] = ((data->type)<<4) + (data->color);
            buf[i][1] = (data->xpos)>>4;
            buf[i][2] = ((data->xpos)<<8) + ((data->level)<<2);
            data++;
            buf[i][4] = ((data->type)<<4) + (data->color);
            buf[i][5] = (data->xpos)>>4;
            buf[i][6] = ((data->xpos)<<8) + ((data->level)<<2);
            buf[i][7] = buf[i][7] + (data->rlcnt);
            if(i<4) data++;
            cansend_tfl(s, i, buf[i]);
            usleep(100); // us
        }
        return;
    }

    这里data是结构体数指针数组,有10个TFL类型的数据;

    参考

    1. socketcan 的使用(一) can raw write: No buffer space available

    2. socket can error write: No buffer space available

  • 相关阅读:
    MVC上传文件并模拟进度条
    C#文件的压缩和解压(ZIP)使用DotNetZip封装类操作zip文件(创建/读取/更新)实例
    Inherits、CodeFile、CodeBehind的区别
    .csproj文件的配置 IIS可以调试
    C# <%@ Register %>指令
    将n行3列的数据dataTable装换成m行7列的dataTable
    在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: 命名管道提供程序, error: 40
    Js全选,插入实现
    Jquery autocomplete插件的使用
    jquery.autocomplete自动补全功能
  • 原文地址:https://www.cnblogs.com/happyamyhope/p/16494372.html
Copyright © 2020-2023  润新知