首页 » 技术SOS » 嵌入式系统 » 操作系统 » socketcan 扩展帧接收异常

socketcan 扩展帧接收异常

菜鸟
2021-09-26 09:15:27     悬赏5分

各位大神们,最近在做linux socketcan,已经弄了好些日子,但是还没搞明白。

问题:

硬件平台:Zynq 7000 ,搭载Ubuntu12.04,socketCAN,500kbps。

/******************************************************************************/

进行socketcan通信开发,在官方提供的例程和驱动下,CAN的标准帧收发测试正常。

但是进行扩展帧收发测试时,发现只有发送正常,接收时ID和DLC正常,数据却都是0。

图片1.pngimage.png

图1:上位机模拟下发给Zynq7000 扩展帧报文

image.png

图2:芯片内部接收ID、DLC正常,data全是0,这块只打印出来了第一个data[0],其它7个数据也全是0.


/******************************************************************************/

下面是主要程序部分:

int RecvBuffer[16][4][10]={0,0,0};//16:means 16 nodes;4:different PFs;10:recv data,include can_id、can_dlcstruct can_frame frame;int count=0;int nbytes;int s;void RecvCAN(void){
        RecvBuffer[0][0][0]=frame.can_id ;
        RecvBuffer[0][0][1]=frame.can_dlc;
        RecvBuffer[0][0][2]=frame.data[0];
        RecvBuffer[0][0][3]=frame.data[1];
        RecvBuffer[0][0][4]=frame.data[2];
        RecvBuffer[0][0][5]=frame.data[0];
        RecvBuffer[0][0][6]=frame.data[4];
        RecvBuffer[0][0][7]=frame.data[5];
        RecvBuffer[0][0][8]=frame.data[6];
        RecvBuffer[0][0][9]=frame.data[7];        //show message
        if (nbytes > 0) {            
         printf("ID=0x%X DLC=%d data[0][0][2]=0x%X\n", RecvBuffer[0][0][0],
                     RecvBuffer[0][0][1],RecvBuffer[0][0][2]);
        }
}
/******************************************************************************/
void SendCAN(void){
    
    frame.can_id = CAN_EFF_FLAG | 0x1C2;
    frame.can_dlc = 8;
    frame.data[0] = 0xA8;
    frame.data[1] = 0xA7;
    frame.data[2] = 0xA6;
    frame.data[3] = 0xA5;
    frame.data[4] = 0xA4;
    frame.data[5] = 0xA3;
    frame.data[6] = 0xA2;
    frame.data[7] = 0xA1;

    nbytes = write(s, &frame, sizeof(frame));  //send message
    if (nbytes != sizeof(frame)) {       
     printf("Send Error frame\n!");
    }    printf("Send Back id[0]=0x%X\n",frame.can_id);
}
/******************************************************************************/
 s = socket(PF_CAN, SOCK_RAW, CAN_RAW);                  //create socket
    printf("can_s is %d\n",s);    strcpy(ifr.ifr_name, "can0" );
    ioctl(s, SIOCGIFINDEX, &ifr);                           //select dev
    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;    printf("ifr_ifindex is %d\n",addr.can_ifindex );
    bind(s, (struct sockaddr *)&addr, sizeof(addr));        //bind
    frame.can_id |= CAN_EFF_FLAG | CAN_RTR_FLAG | CAN_EFF_MASK;    
    while(1)
    {
        SendCAN();//send the command

        nbytes = read(s, &frame, sizeof(frame));   //recv protocol
        printf("can_r_nbytes is %d\n",nbytes);       
         printf("frame.can_id is 0x%X\n",frame.can_id & CAN_EFF_MASK);       
          if (nbytes < 0) {
                perror("can raw socket read");              
                  return -2;
        }       
         /* paranoid check ... */
        if (nbytes < sizeof(struct can_frame)) {                
        fprintf(stderr, "read: incomplete CAN frame\n");               
         return -3;
        }       
         //for test
        RecvCAN();//recv the data and save the data to a buffer
    } 
    /******************************************************************************/



分享
关键词: socketcan, linux