【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

posted on 2022-07-25 18:39  鹅要长大  阅读(2032)  评论(0编辑  收藏  举报

导航